Xamarin Forms : Hide Editor or Entry underline - xamarin.forms

I am using an editor in my UI. But the black underline is irritating, is there any way to remove that underline?
Thanks in advance

I have done the entry and editor underline removal features using custom renders.
##In PCL##
CustomEntry.cs
using Xamarin.Forms;
namespace Entry_Editor_Sample
{
public class CustomEntry : Entry
{
}
}
CustomEditor.cs
using Xamarin.Forms;
namespace Entry_Editor_Sample
{
public class CustomEditor : Editor
{
}
}
##In android##
CustomEntryRenderer.cs
using Android.Content;
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.Text;
using Entry_Editor_Sample;
using Entry_Editor_Sample.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Entry_Editor_Sample.Droid
{
class CustomEntryRenderer : EntryRenderer
{
public CustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
GradientDrawable gd = new GradientDrawable();
gd.SetColor(global::Android.Graphics.Color.Transparent);
this.Control.SetBackgroundDrawable(gd);
this.Control.SetRawInputType(InputTypes.TextFlagNoSuggestions);
//Control.SetHintTextColor(ColorStateList.ValueOf(global::Android.Graphics.Color.White));
}
}
}
}
CustomEditorRenderer.cs
using Android.Content;
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.Text;
using Entry_Editor_Sample;
using Entry_Editor_Sample.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomEditor), typeof(CustomEditorRenderer))]
namespace Entry_Editor_Sample.Droid
{
class CustomEditorRenderer : EditorRenderer
{
public CustomEditorRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Control != null)
{
GradientDrawable gd = new GradientDrawable();
gd.SetColor(global::Android.Graphics.Color.Transparent);
this.Control.SetBackgroundDrawable(gd);
this.Control.SetRawInputType(InputTypes.TextFlagNoSuggestions);
//Control.SetHintTextColor(ColorStateList.ValueOf(global::Android.Graphics.Color.Black));
}
}
}
}
##In IOS##
CustomEntryRenderer.cs
using Entry_Editor_Sample;
using Entry_Editor_Sample.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Entry_Editor_Sample.iOS
{
class CustomEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.BorderStyle = UITextBorderStyle.None;
Control.Layer.CornerRadius = 10;
//Control.TextColor = UIColor.Black;
}
}
}
}
CustomEditorRenderer.cs
using Entry_Editor_Sample;
using Entry_Editor_Sample.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CustomEditor), typeof(CustomEditorRenderer))]
namespace Entry_Editor_Sample.iOS
{
class CustomEditorRenderer : EditorRenderer
{
public CustomEditorRenderer()
{
UIKeyboard.Notifications.ObserveWillShow((sender, args) =>
{
if (Element != null)
{
Element.Margin = new Thickness(0, 0, 0, args.FrameEnd.Height); //push the entry up to keyboard height when keyboard is activated
}
});
UIKeyboard.Notifications.ObserveWillHide((sender, args) =>
{
if (Element != null)
{
Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed
}
});
}
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Layer.CornerRadius = 10;
Control.TextColor = UIColor.Black;
}
}
}
}
##Finally in MainPage.xaml##
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Entry_Editor_Sample"
mc:Ignorable="d"
BackgroundColor="White"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
x:Class="Entry_Editor_Sample.MainPage">
<StackLayout
VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand"
BackgroundColor="White">
<local:CustomEntry
BackgroundColor="SkyBlue"
Placeholder="Entry"
PlaceholderColor="Black"
TextColor="Black"/>
<local:CustomEditor
BackgroundColor="SkyBlue"
Placeholder="Editor"
HeightRequest="100"
PlaceholderColor="Black"
TextColor="Black"/>
</StackLayout>
</ContentPage>
I uploaded a sample on here :)

Create a custom renderer in your Android project:
public class CustomEntryRenderer : EntryRenderer {
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) {
base.OnElementChanged(e);
Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
Then in your XAML:
<ContentPage xmlns:xyz="clr-namespace:PclNamespaceForCustomControls">
...
<xyz:CustomEntry Placeholder="Lorem ipsum" />
</ContentPage>
See Microsoft docs for more info: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/entry

You can use custom renderers to achieve entry and editor underline removal.
I am using the below code to apply these feature for all entries and editors in the project and it is working with Xamarin Forms 4.8+
Xamarin Android
Entry
[assembly: ExportRenderer(typeof(Entry), typeof(EntryRendererAndroid), new[] { typeof(VisualMarker.DefaultVisual) })]
namespace XFTest.Droid.Renderers
{
public class EntryRendererAndroid : EntryRenderer
{
public EntryRendererAndroid(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Background = null;
Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
}
}
Editor
[assembly: ExportRenderer(typeof(Editor), typeof(EditorRendererAndroid), new[] { typeof(VisualMarker.DefaultVisual) })]
namespace XFTest.Droid.Renderers
{
public class EditorRendererAndroid : EditorRenderer
{
public EditorRendererAndroid(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Background = null;
Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
}
}
Xamarin iOS
Entry
[assembly: ExportRenderer(typeof(Entry), typeof(EntryRendereriOS), new[] { typeof(VisualMarker.DefaultVisual) })]
namespace XFTest.iOS.Renderers
{
public class EntryRendereriOS : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.BackgroundColor = UIColor.FromWhiteAlpha(1, 1);
Control.Layer.BorderWidth = 0;
Control.BorderStyle = UITextBorderStyle.None;
}
}
}
}
Editor
[assembly: ExportRenderer(typeof(Entry), typeof(EntryRendereriOS), new[] { typeof(VisualMarker.DefaultVisual) })]
namespace XFTest.iOS.Renderers
{
public class EntryRendereriOS : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.BackgroundColor = UIColor.FromWhiteAlpha(1, 1);
Control.Layer.BorderWidth = 0;
Control.BorderStyle = UITextBorderStyle.None;
}
}
}
}

Related

Automatic height of the webview

I have a xamarin forms application and I have inserted a webview inside the layout stack, the problem is that I have multiple pages and in each page the length of the content is different from the others.
I wanted to ask if there was a way to have the webview automatically adjust the height.
I have read other similar questions on the site, but I admit they seemed confusing to me.
This is my code xaml
<ContentPage.Content>
<StackLayout Padding="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Spacing="0" BackgroundColor="White">
<WebView
x:Name="wvSite"
VerticalOptions="FillAndExpand"
HeightRequest="2300" />
</StackLayout>
</ContentPage.Content>
You could reset the webview height according to the content height when loading page finished via custom renderer.
Android:
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))]
namespace App1.Droid
{
public class CustomWebViewRenderer : WebViewRenderer
{
public CustomWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
Control.SetWebViewClient(new CustomWebViewClient(e.NewElement));
}
}
internal class CustomWebViewClient : Android.Webkit.WebViewClient
{
private WebView webView;
public CustomWebViewClient(WebView webView)
{
this.webView = webView;
}
public async override void OnPageFinished(Android.Webkit.WebView view, string url)
{
if (webView != null)
{
int i = 10;
while (view.ContentHeight == 0 && i-- > 0)
await System.Threading.Tasks.Task.Delay(100);
webView.HeightRequest = view.ContentHeight;
}
base.OnPageFinished(view, url);
}
}
}
iOS:
[assembly: ExportRenderer(typeof(WebView),
typeof(CustomWebviewRenderer))]
namespace App1.iOS
{
public class CustomWebviewRenderer : WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
NavigationDelegate = new CustomWebviewNavigationDelegate();
}
}
internal class CustomWebviewNavigationDelegate : WKNavigationDelegate
{
[Export("webview:didFinishNavigation:")]
public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
//base.DidFinishNavigation(webView, navigation);
webView.Frame = new CoreGraphics.CGRect(0, 0, webView.ScrollView.ContentSize.Width, webView.ScrollView.ContentSize.Height);
}
}
}

Xamarin Forms Shell TabBar Rounded Corner

I'd like to know if there's a renderer to allows me to use a rounded corner in the tabbar using Shell, like in the image above.
You could do it in your custom shellrenderer :
create the MyShellRenderer in your android project:
[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace your namepace
{
class MyShellRenderer:ShellRenderer
{
public MyShellRenderer(Context context) : base(context)
{
}
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
return new MyShellBottomNavViewAppearanceTracker();
}
}
}
define the MyShellBottomNavViewAppearanceTracker:
namespace ShellDemo.Droid
{
class MyShellBottomNavViewAppearanceTracker : IShellBottomNavViewAppearanceTracker
{
public void Dispose()
{
}
public void ResetAppearance(BottomNavigationView bottomView)
{
}
public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
bottomView.SetBackgroundResource(Resource.Drawable.bottombackground);
}
}
}
create the round corner drawable bottombackground.xml in your Resources/drawable:
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f00" />
<corners android:topLeftRadius="20dp"
android:topRightRadius="20dp"
/>
</shape>
the effect :
Update for ios:
the similar to android
MyShellRenderer:ShellRenderer class
[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace your namepace
{
class MyShellRenderer:ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new MyShellTabBarAppearanceTrancker();
}
}
}
MyShellTabBarAppearanceTrancker class:
class MyShellTabBarAppearanceTrancker : IShellTabBarAppearanceTracker
{
public void Dispose()
{
}
public void ResetAppearance(UITabBarController controller)
{
}
public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
UIBezierPath uIBezierPath = UIBezierPath.FromRoundedRect(controller.TabBar.Bounds, UIRectCorner.TopLeft | UIRectCorner.TopRight, new CoreGraphics.CGSize(30, 30));
CAShapeLayer cAShapeLayer = new CAShapeLayer();
cAShapeLayer.Frame = controller.TabBar.Bounds;
cAShapeLayer.Path = uIBezierPath.CGPath;
controller.TabBar.Layer.Mask = cAShapeLayer;
}
public void UpdateLayout(UITabBarController controller)
{
}
}

how to scroll to top in editor when user stop writing in xamarin forms

i tried from scrolToAsync method but not working .on xaml when stop writing message or
keyboard keydown button is pressed control goes to start of message.when keyboard
keydown click,editor control goes to start of the message.
i use this method on editor propertyChanged.
double iScrollPosition = 0;
await editorScrollView.ScrollToAsync(0, iScrollPosition, true);
<Frame Margin="10">
<ScrollView x:Name="editorScrollView" >
<Editor x:Name="txtEditor"
HeightRequest="110"
Placeholder="Write message here"
PropertyChanged="OnStatusLabelPropertyChanged" />
</ScrollView>
</Frame>
can anyone please help me with this
You can use CustomRenderer and implement it in specific platforms.
in Android
using Android.Content;
using xxx.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Android.Widget.TextView;
[assembly: ExportRenderer(typeof(Editor), typeof(MyEditorRenderer))]
namespace xxx.Droid
{
public class MyEditorRenderer : EditorRenderer
{
public MyEditorRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if(Control!=null)
{
Control.FocusChange += Control_FocusChange;
}
}
private void Control_FocusChange(object sender, FocusChangeEventArgs e)
{
if(!e.HasFocus)
{
Control.SetSelection(0);
}
}
}
}
in iOS
using System;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using xxx.iOS;
[assembly:ExportRenderer(typeof(Editor),typeof(MyEditorRenderer))]
namespace xxx.iOS
{
public class MyEditorRenderer:EditorRenderer,IUITextViewDelegate
{
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if(Control!=null)
{
Control.Ended += Control_Ended;
}
}
private void Control_Ended(object sender, EventArgs e)
{
var editor = sender as UITextView;
editor.ScrollRangeToVisible(new NSRange(0,0));
}
}
}

Xamarin Forms Android search bar remove underline

Hopefully this doesn't get dinged, I've looked at other posts and nothing seems to work.
Code:
<controls:SearchPageSearchBar Grid.Column="1" Scale=".8" Margin="0,0,0,0" x:Name="searchBar"
BackgroundColor="White"
SearchCommandParameter="{Binding Text, Source={x:Reference searchBar}}"
Placeholder="Search" >
</controls:SearchPageSearchBar>
public class SearchPageSearchBarDroid : SearchBarRenderer
{
public SearchPageSearchBarDroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> args)
{
base.OnElementChanged(args);
var plateId = Resources.GetIdentifier("android:id/search_plate", null, null);
var plate = Control.FindViewById(plateId);
plate.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
Tried all solutions here too
https://forums.xamarin.com/discussion/140247/how-can-i-remove-the-underline-in-searbar-on-android
[assembly: ExportRenderer(typeof(SearchPageSearchBar), typeof(SearchPageSearchBarDroid))]
i test your code and it works,have you missed the above line in your SearchPageSearchBarDroid ?
[assembly: ExportRenderer(typeof(SearchPageSearchBar), typeof(SearchPageSearchBarDroid))]
namespace App18.Droid
{
class SearchPageSearchBarDroid:SearchBarRenderer
{
public SearchPageSearchBarDroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
var plateId = Resources.GetIdentifier("android:id/search_plate", null, null);
var plate = Control.FindViewById(plateId);
plate.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
}

The underline of entry cannot removed

I want to make a entry that without underline. I tried two solutions but both can not work well.
Control.Background = null;
it is not go well and I take another solution:
GradientDrawable gd = new GradientDrawable();
gd.SetColor(global::Android.Graphics.Color.Transparent);
Control.SetBackground(gd);
this.Control.SetRawInputType(Android.Text.InputTypes.TextFlagNoSuggestions);
Control.SetHintTextColor(ColorStateList.ValueOf(global::Android.Graphics.Color.White));
It also not go well in android but work well in ios.I do not understand why.
You can try add xml styling named editText_bg.xml,
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#2f6699" />
<corners
android:radius="10dp"
/>
</shape>
And you can give this to entry as background resource :
[assembly: ExportRenderer(typeof(CustomEntry), typeof(AndroidCustomEntryRenderer))]
namespace XXX.Droid.Renderer
{
public class AndroidCustomEntryRenderer : EntryRenderer
{
public AndroidCustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.SetBackgroundColor(global::Android.Graphics.Color.White);
Control.SetBackgroundResource(Resource.Drawable.edittext_bg);
}
}
}
}
Try my implementation(working for Android and ios). PlainEntry is empty class inherited from Xamarin.Forms.Entry
Android
[assembly: ExportRenderer(typeof(PlainEntry), typeof(PlainEntryRenderer))]
namespace UR.Droid.Renderers
{
public class PlainEntryRenderer : EntryRenderer
{
public PlainEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
this.Control.
SetBackgroundColor(global::Android.Graphics.Color.Transparent);
Control.SetPadding(0, 0, 0, 0);
}
}
}
}
iOS
[assembly: ExportRenderer(typeof(PlainEntry), typeof(PlainEntryRenderer))]
namespace UR.iOS.Renderer
{
class PlainEntryRenderer: EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.BorderStyle = UITextBorderStyle.None;
Control.BackgroundColor = UIColor.FromRGBA(0, 0, 0, 0);
}
}
}
}
If you want to use renderers for all Xamarin.Forms.Entry like not the than specify:
[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(PlainEntryRenderer))]

Resources