How to change searchbar cancel button image in xamarin forms - xamarin

I have used custom renderer to change the search bar underline color. But i don't know how to change the cancel button cross symbol(X) to image as shown in the attached screenshot. My custom renderer is as below,
public class CustomSearchBarRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
LinearLayout linearLayout = this.Control.GetChildAt(0) as LinearLayout;
linearLayout = linearLayout.GetChildAt(2) as LinearLayout;
linearLayout = linearLayout.GetChildAt(1) as LinearLayout;
GradientDrawable gd = new GradientDrawable();
gd.SetStroke(0, Android.Graphics.Color.LightGray);
linearLayout.Background = gd;
AutoCompleteTextView textView = linearLayout.GetChildAt(0) as AutoCompleteTextView;
}
}
}

How to change searchbar cancel button image in xamarin forms
Modify your code like this :
public class MySearchBarRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.SearchBar> e)
{
base.OnElementChanged(e);
if (Control != null)
{
var searchView = Control;
int searchViewCloseButtonId = Control.Resources.GetIdentifier("android:id/search_close_btn", null, null);
var closeIcon = searchView.FindViewById(searchViewCloseButtonId);
(closeIcon as ImageView).SetImageResource(Resource.Drawable.cancel_icon);
}
}
}
Effect.

You can use renderer like this for your code
using System;
using Android.Content;
using Android.Graphics.Drawables;
using Android.Support.V4.Content;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using CustomRenderers
[assembly: ExportRenderer(typeof(SearchBar), typeof(CustomSearchBarRenderer))]
namespace CustomRenderers
{
public class CustomSearchBarRenderer : SearchBarRenderer
{
Context context;
public CustomSearchBarRenderer(Context context) : base(context)
{
this.context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (Control == null)
{
return;
}
if (e.OldElement == null)
{
//remove the underline line of the edittext
LinearLayout linearLayout = this.Control.GetChildAt(0) as LinearLayout;
linearLayout = linearLayout?.GetChildAt(2) as LinearLayout;
linearLayout = linearLayout?.GetChildAt(1) as LinearLayout;
if (linearLayout != null)
{
//set transparent to remove the underline line of edittext
linearLayout.SetBackground(new ColorDrawable(Android.Graphics.Color.Transparent));
}
}
//set rounded background
Control.Background = ContextCompat.GetDrawable(Context, Resource.Drawable.RoundedSearchViewRectangle);
//abc_ic_clear_material is system clear icon which is in gray color
ImageView searchClose = (ImageView)Control.FindViewById(context.Resources.GetIdentifier("android:id/search_close_btn", null, null));
searchClose?.SetImageResource(Resource.Drawable.abc_ic_clear_material);
}
}
}
this is the Resources\Drawable\RoundedSearchViewRectangle.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="20dp" />
<solid android:color="#ffff80" />
</shape>
Before apply this code, we have
it will looks like this before and after apply these code:
and you can change the icon of it with this code
searchClose?.SetImageResource(Resource.Drawable.ic_stop);
it will looks like this
If you want a clear button with gray circle around it, you can set background:
searchClose.SetBackgroundResource(Resource.Drawable.SearchViewClearButton);
Resources\Drawable\SearchViewClearButton.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="12dp"
android:useLevel="false">
<solid android:color="#a9a9a9" />
</shape>
</item>
</layer-list>
and it will look like this:
If you want to hide the cancel button, you can use this code
Control.ShowsCancelButton = false;

Related

Xamarin IOS Custom Renderer overriden Draw method not called

I am trying to load a customized slider control in a listview (with accordeon behaviour). When the View loads all the listview elements are collapsed so the slider control visibility is false. I observed that the overriden Draw method within the ios renderer is not called while the control is not visible so I end up having the native control within my listview.
I have reproduced the issue in a separate project:
I have the IOS custom renderer:
public class CustomGradientSliderRenderer : SliderRenderer
{
public CGColor StartColor { get; set; }
public CGColor CenterColor { get; set; }
public CGColor EndColor { get; set; }
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
{
if (Control == null)
{
var customSlider = e.NewElement as CustomGradientSlider;
StartColor = customSlider.StartColor.ToCGColor();
CenterColor = customSlider.CenterColor.ToCGColor();
EndColor = customSlider.EndColor.ToCGColor();
var slider = new SlideriOS
{
Continuous = true,
Height = (nfloat)customSlider.HeightRequest
};
SetNativeControl(slider);
}
base.OnElementChanged(e);
}
public override void Draw(CGRect rect)
{
base.Draw(rect);
if (Control != null)
{
Control.SetMinTrackImage(CreateGradientImage(rect.Size), UIControlState.Normal);
}
}
void OnControlValueChanged(object sender, EventArgs eventArgs)
{
((IElementController)Element).SetValueFromRenderer(Slider.ValueProperty, Control.Value);
}
public UIImage CreateGradientImage(CGSize rect)
{
var gradientLayer = new CAGradientLayer()
{
StartPoint = new CGPoint(0, 0.5),
EndPoint = new CGPoint(1, 0.5),
Colors = new CGColor[] { StartColor, CenterColor, EndColor },
Frame = new CGRect(0, 0, rect.Width, rect.Height),
CornerRadius = 5.0f
};
UIGraphics.BeginImageContext(gradientLayer.Frame.Size);
gradientLayer.RenderInContext(UIGraphics.GetCurrentContext());
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image.CreateResizableImage(UIEdgeInsets.Zero);
}
}
public class SlideriOS : UISlider
{
public nfloat Height { get; set; }
public override CGRect TrackRectForBounds(CGRect forBounds)
{
var rect = base.TrackRectForBounds(forBounds);
return new CGRect(rect.X, rect.Y, rect.Width, Height);
}
}
The View with codebehind:
Main.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="GradientSlider.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:GradientSlider">
<ContentPage.Content>
<Grid>
<StackLayout x:Name="SliderContainer">
<local:CustomGradientSlider
x:Name="mySlider"
CenterColor="#feeb2f"
CornerRadius="16"
EndColor="#ba0f00"
HeightRequest="20"
HorizontalOptions="FillAndExpand"
Maximum="10"
Minimum="0"
StartColor="#6bab29"
VerticalOptions="CenterAndExpand"
MaximumTrackColor="Transparent"
ThumbColor="green"
/>
<Label x:Name="lblText" Text="txt"
VerticalOptions="Center" HorizontalOptions="Center"/>
</StackLayout>
<Button Text="Magic" Clicked="Button_Tapped" WidthRequest="100" HeightRequest="50" VerticalOptions="Center" HorizontalOptions="Center"/>
</Grid>
</ContentPage.Content>
</ContentPage>
Main.xaml.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace GradientSlider
{
public partial class MainPage : ContentPage, INotifyPropertyChanged
{
public MainPage()
{
InitializeComponent();
SliderContainer.IsVisible = false;
}
void Button_Tapped(object sender,ClickedEventArgs a)
{
SliderContainer.IsVisible = !SliderContainer.IsVisible;
}
}
}
So in the scenario above you can see that when I load the main.xaml the control is invisible (SliderContainer.IsVisible = false;) in this case I get a native slider control and not my custom one. If I change in the constructor SliderContainer.IsVisible = true; then I get my custom control.
After an investigation I realised that if the control is not visible when the view loads the public override void Draw(CGRect rect) is not called. I could not find any solution to trigger the Draw method while the control is invisible.
Anybody has an idea how to load a custom renderer correctly while the control is not visible ?
Thank you!
Assuming the renderer is overriding OnElementPropertyChanged:
protected override void OnElementChanged(ElementChangedEventArgs<MyFormsSlider> e)
{
if (e.NewElement != null)
{
if (Control == null)
{
// Instantiate the native control and assign it to the Control property with
// the SetNativeControl method
SetNativeControl(new MyNativeControl(...
...
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
//assuming MyFormsSlider derives from View / VisualElement; the latter has IsVisibleProperty
if (e.PropertyName == MyFormsSlider.IsVisibleProperty.PropertyName)
{
//Control is the control set with SetNativeControl
Control. ...
}
...
}

Is there a way to center the page title on Android when using Xamarin Forms Shell?

I recently changed to Xamarin Forms and notice that the title isn't centered at the top of the page for Android devices.
Is there a way that I can do this?
Here's an example of what I mean with the title:
You can use the TitleView:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TitleViewSample"
x:Class="TitleViewSample.MainPage">
<NavigationPage.TitleView>
<Label Text="Hello World" HorizontalTextAlignement="Center"/>
</NavigationPage.TitleView>
<ContentPage.Content>
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
https://www.andrewhoefling.com/Blog/Post/xamarin-forms-title-view-a-powerful-navigation-view
You will have to implement ShellRenderer in this case as you have Xamarin.Forms Shell Project.
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using Android.App;
using Android.Content;
using Android.Content.Res;
using Android.Support.V4.Widget;
using Android.Support.V7.Widget;
using Android.Util;
using Android.Widget;
using Japanese.Droid.CustomRenderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Toolbar = Android.Support.V7.Widget.Toolbar;
[assembly: ExportRenderer(typeof(Xamarin.Forms.Shell), typeof(MyShellRenderer))]
namespace MyProject.Droid.CustomRenderers
{
public class MyShellRenderer : ShellRenderer
{
public MyShellRenderer(Context context) : base(context)
{
}
protected override IShellToolbarAppearanceTracker CreateToolbarAppearanceTracker()
{
return new MyShellToolbarAppearanceTracker(this);
}
protected override IShellToolbarTracker CreateTrackerForToolbar(Toolbar toolbar)
{
return new MyShellToolbarTracker(this, toolbar, ((IShellContext)this).CurrentDrawerLayout);
}
}
public class MyShellToolbarAppearanceTracker : ShellToolbarAppearanceTracker
{
public MyShellToolbarAppearanceTracker(IShellContext context) : base(context)
{
}
public override void SetAppearance(Android.Support.V7.Widget.Toolbar toolbar, IShellToolbarTracker toolbarTracker, ShellAppearance appearance)
{
base.SetAppearance(toolbar, toolbarTracker, appearance);
//Change the following code to change the icon of the Header back button.
toolbar?.SetNavigationIcon(Resource.Drawable.back);
}
}
public class MyShellToolbarTracker : ShellToolbarTracker
{
public MyShellToolbarTracker(IShellContext shellContext, Toolbar toolbar, DrawerLayout drawerLayout) : base(shellContext, toolbar, drawerLayout)
{
}
protected override void UpdateTitleView(Context context, Toolbar toolbar, View titleView)
{
base.UpdateTitleView(context, toolbar, titleView);
for (int index = 0; index < toolbar.ChildCount; index++)
{
if (toolbar.GetChildAt(index) is TextView)
{
var title = toolbar.GetChildAt(index) as TextView;
//Change the following code to change the font size of the Header title.
title.SetTextSize(ComplexUnitType.Sp, 20);
toolbar.SetTitleMargin(MainActivity.displayMetrics.WidthPixels / 4 - Convert.ToInt32(title.TextSize) - title.Text.Length / 2, 0, 0, 0);
}
}
}
}
}
Here is the code for MainActivity.cs
public class MainActivity : FormsAppCompatActivity
{
public static DisplayMetrics displayMetrics;
protected override void OnCreate(Bundle savedInstanceState)
{
Window.AddFlags(WindowManagerFlags.Fullscreen);
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
displayMetrics = new DisplayMetrics();
WindowManager.DefaultDisplay.GetRealMetrics(displayMetrics);
LoadApplication(new App());
if (Window != null) Window.SetStatusBarColor(Android.Graphics.Color.Transparent);
if (isPhone(this)) RequestedOrientation = ScreenOrientation.Portrait;
}
}
As the title textview having wrapped width within toolbar not updating alignment on TextAlignment with center, you can update the layout params of the toolbar to matchparent and textview gravity as follows.
If the hamburger image added with custom image then need check that resoulution if that is too big just reduce it lower one
[assembly: ExportRenderer(typeof(MainPage), typeof(MyRenderer))]//MainPage - navigation page
namespace MyProject.Droid
{
public class MyRenderer: MasterDetailPageRenderer
{
public MyRenderer(Context context) : base(context)
{
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
var toolbar = FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.toolbar);
for (var i = 0; i < toolbar.ChildCount; i++)
{
var title = toolbar.GetChildAt(i) as TextView;
if (title != null && !string.IsNullOrEmpty(title.Text))
{
title.TextAlignment = Android.Views.TextAlignment.Center;
title.Gravity = GravityFlags.CenterHorizontal;
var layoutParams = (AndroidX.AppCompat.Widget.Toolbar.LayoutParams)title.LayoutParameters;
layoutParams.Width = ViewGroup.LayoutParams.MatchParent;
toolbar.RequestLayout();
}
}
}
}
}

Xamarin: How to change Stepper color in Android to look like in iOS?

I have Xamarin PCL app which uses Stepper. I wanted to change the color of my Stepper button and now using the following renderer.
In PCL:
public class MyStepper : Stepper
{
public static readonly BindableProperty ColorProperty =
BindableProperty.Create(nameof(Color), typeof(Color), typeof(MyStepper), Color.Default);
public Color MyColor
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
}
In iOS:
public class MyStepperRenderer : StepperRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
Control.TintColor = s.MyColor.ToUIColor();
}
}
In Android:
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
{
Control.GetChildAt(0).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
In XAML:
<local:MyStepper MyColor="Red" Maximum="10" Minimum="0" ....... />
As expected it would work like the images attached. But is it possible to make the Android color to change just the "outline" of the button like what it looks like in iOS?
How about changing the colors of the - and + also to red. Is there a way to do that also?
Based on #Sven-Michael Stübe's answer, I add some code to change the "-" and "+" color:
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
{
var button = Control.GetChildAt(0) as Android.Widget.Button;
button.SetTextColor(s.MyColor.ToAndroid());
button.SetBackground(ResourcesCompat.GetDrawable(Resources, Resource.Drawable.button_selector, null));
button.Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
var button2 = Control.GetChildAt(1) as Android.Widget.Button;
button2.SetTextColor(s.MyColor.ToAndroid());
button2.SetBackground(ResourcesCompat.GetDrawable(Resources, Resource.Drawable.button_selector, null));
button2.Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
Effectt.
go and create a the drawable with the states and set them in your Renderer instead of setting a single color.
Sven-Michael Stübe wanna say that if you set a single color as a background, then your Button will have no click effect. You could refer to: Material effect on button with background color
for more detail information.
For example:
button_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorAccent" android:state_pressed="true"/>
<item android:drawable="#color/colorPrimaryDark" android:state_focused="true"/>
<item android:drawable="#drawable/button_border"/>
</selector>
button_border.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#00FFFFFF" />
<corners android:radius="5dp" />
<stroke
android:width="2dp"
android:color="#FFFFFF" />
</shape>
You can do it if you create a custom vector drawable
button_border.xml
Place this file in your Android Resources\drawable folder and ensure the build action is set to AndroidResource
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#00FFFFFF" />
<corners android:radius="5dp" />
<stroke
android:width="2dp"
android:color="#FFFFFF" />
</shape>
MyStepperRenderer.cs
Then you just need to set it as background of your two buttons.
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
var s = Element as MyStepper;
if (Control != null)
{
Control.GetChildAt(0).SetBackground(Resources.GetDrawable(Resource.Drawable.button_border));
Control.GetChildAt(1).SetBackground(Resources.GetDrawable(Resource.Drawable.button_border));
Control.GetChildAt(0).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
This will look like:
discussion
You loose states like pressed, disabled, ... (see https://developer.android.com/guide/topics/resources/color-list-resource.html)
If you don't have many different colors, go and create a the drawable with the states and set them in your Renderer instead of setting a single color. So your user will get a better feedback.

Xamarin forms Shadow on Frame in Android

The Frame class in Xamarin Forms is quite limited, and can't allow me to get a shadow behind the Frame. I've made a custom renderer for iOS using this code:
public class RatingInfoFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
Layer.BorderColor = UIColor.White.CGColor;
Layer.CornerRadius = 10;
Layer.MasksToBounds = false;
Layer.ShadowOffset = new CGSize(-2, 2);
Layer.ShadowRadius = 5;
Layer.ShadowOpacity = 0.4f;
}
}
Making a similar one on Android is causing me problems, since my knowledge on Android native is kind of limited. Could anyone tell me what to look at, perhaps some good code example? I haven't found anything that looks similar to this.
It can be very easy in Android platform, but first of all, you need to create your shadow under Drawable folder of Android resources. For example:
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#CABBBBBB" />
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
Name this file as "shadow.xml" and place it under the Drawable folder of Android project, then in your RatingInfoFrameRenderer:
public class RatingInfoFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
ViewGroup.SetBackgroundResource(Resource.Drawable.shadow);
}
}
}
To change the style of shadow, you can modify the shadow.xml file, for more information about this, you may refer to google's official document: LayerList.
I know this question is old, but there is an updated way of getting a better shadow effect then the accepted answer. inherit from Xamarin.Forms.Platform.Android.FastRenderers.FrameRenderer and then use SetOutlineSpotShadowColor(Color color) to set the shadow color. You can use CardElevation to determine the strength and spread of the shadow as well.
[assembly: ExportRenderer(typeof(Myframe), typeof(MyFrameRenderer))]
namespace MyApp.Droid.Renderers
{
public class MyFrameRenderer: Xamarin.Forms.Platform.Android.FastRenderers.FrameRenderer
{
public MyFrameRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
CardElevation = 10;
if(((App)Application.Current).Theme != Core.Enums.Theme.Dark)
{
SetOutlineSpotShadowColor(Xamarin.Forms.Color.Gray.ToAndroid());
}
else
{
SetOutlineSpotShadowColor(Xamarin.Forms.Color.HotPink.ToAndroid());
}
}
}
}
Hope this helps someone who stumbles in here like I did.
I was able to get a shadow effect in Xamarin Forms for a box view, I'm pretty sure it can used similarly for a Frame. I got the clue from Android Documentation
I added a new property called HasShadow
public static readonly BindableProperty HasShadowProperty =
BindableProperty.Create("HasShadow", typeof(bool), typeof(ExtendedBoxView), false);
public bool HasShadow
{
get { return (bool)GetValue(HasShadowProperty); }
set { SetValue(HasShadowProperty, value); }
}
Here's the code for the Renderer in Android
public class ExtendedBoxViewRenderer : BoxRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
{
base.OnElementChanged(e);
var element = e.NewElement as ExtendedBoxView;
if (element == null) return;
if (element.HasShadow)
{
ViewGroup.Elevation = 8.0f;
ViewGroup.TranslationZ = 10.0f;
}
}
}
And this is how it looks
UPDATE
I found out that this approach causes app crash for older versions of Android. Although I haven't found a way to display Shadows in Android versions prior to Lollipop. This will prevent any app crashes
public class ExtendedBoxViewRenderer : BoxRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
{
base.OnElementChanged(e);
var element = e.NewElement as ExtendedBoxView;
if (element == null) return;
if (element.HasShadow)
{
//For some reason ViewCompat has issues when running in debug hence the workaround.
#if DEBUG
double dAndroidVersion;
if (double.TryParse(Build.VERSION.Release, out dAndroidVersion))
{
if (dAndroidVersion < 21)
return;
}
#else
ViewCompat.SetElevation(ViewGroup, 8.0f);
ViewCompat.SetTranslationZ(ViewGroup, 10.0f);
#endif
}
}
}

Xamarin WebView scale to fit

Is there a way to set a WebView in Xamarin to scale its content to fit the screen by default and still allow for pinch zooming in/out?
We're going to use this to display documents we have online.
I solved the scale fit to page and zooming by Custom Renderers, as given below
For IOS
public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
var view = Element as CustomWebView;
if (view == null || NativeView == null)
{
return;
}
this.ScalesPageToFit = true;
}
}
For Android
public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Settings.BuiltInZoomControls = true;
Control.Settings.DisplayZoomControls = false;
Control.Settings.LoadWithOverviewMode = true;
Control.Settings.UseWideViewPort = true;
}
}
}
If you're using Xamarin.Forms that would look something like this
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebViewDemo.LoadingDemo" Title="Loading Demo">
<ContentPage.Content>
<StackLayout>
<WebView x:Name="Browser"
VerticalOptions = LayoutOptions.FillAndExpand ,
HorizontalOptions = LayoutOptions.FillAndExpand,
</StackLayout>
</ContentPage.Content>
</ContentPage>
This should fill the page and not affect pinch and zoom.

Resources