Just thought I'd throw this out there. If you want floating labels on your Entry (as found here (by JamesMontemagno)), I've thrown together a custom renderer that extends Entry
.
note: this requires the AppCompat stuff to be enabled in your Android App.
First you want to create an axml view and drop it in your /Resources/layout
directory.
TextInputLayout.axml
<!-- NOTE: MyAppCompatTheme is important - it MUST apply an AppCompat theme of some sort -->
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TextInputLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textInputLayout"
android:theme="@style/MyAppCompatTheme">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
From there, just drop this renderer into your Droid Renderers directory (wherever that lives).
MaterialEntryRenderer_Droid.cs
using System.ComponentModel;
using Android.Support.Design.Widget;
using Android.Text;
using Android.Views;
using MyApp.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Application = Android.App.Application;
using TextChangedEventArgs = Android.Text.TextChangedEventArgs;
using View = Android.Views.View;
[assembly: ExportRenderer(typeof (Entry), typeof (MaterialEntryRenderer_Droid))]
namespace MyApp.Droid.Renderers
{
public class MaterialEntryRenderer_Droid : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<Entry, View>
{
private TextInputLayout _nativeView;
private TextInputLayout NativeView
{
get { return _nativeView ?? (_nativeView = InitializeNativeView()); }
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
var ctrl = CreateNativeControl();
SetNativeControl(ctrl);
SetText();
SetHintText();
SetBackgroundColor();
SetTextColor();
SetIsPassword();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Entry.PlaceholderProperty.PropertyName)
{
SetHintText();
}
if (e.PropertyName == Entry.TextColorProperty.PropertyName)
{
SetTextColor();
}
if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
{
SetBackgroundColor();
}
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
{
SetIsPassword();
}
if (e.PropertyName == Entry.TextProperty.PropertyName)
{
SetText();
}
}
private void EditTextOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
{
Element.Text = textChangedEventArgs.Text.ToString();
NativeView.EditText.SetSelection(Element.Text.Length);
}
private void SetText()
{
NativeView.EditText.Text = Element.Text;
}
private void SetIsPassword()
{
NativeView.EditText.InputType = Element.IsPassword
? InputTypes.TextVariationPassword | InputTypes.ClassText
: NativeView.EditText.InputType;
}
public void SetBackgroundColor()
{
NativeView.SetBackgroundColor(Element.BackgroundColor.ToAndroid());
}
private void SetHintText()
{
NativeView.Hint = Element.Placeholder;
}
private void SetTextColor()
{
if (Element.TextColor == Color.Default)
{
NativeView.EditText.SetTextColor(NativeView.EditText.TextColors);
}
else
{
NativeView.EditText.SetTextColor(Element.TextColor.ToAndroid());
}
}
private TextInputLayout InitializeNativeView()
{
var view = FindViewById<TextInputLayout>(Resource.Id.textInputLayout);
view.EditText.TextChanged += EditTextOnTextChanged;
return view;
}
protected override View CreateNativeControl()
{
return LayoutInflater.From(Application.Context).Inflate(Resource.Layout.TextInputLayout, null);
}
}
}
Disclaimer: I am not responsible for your issues - if you have questions or enhancements, post them below.
This renderer currently only supports the following properties.
- TextColor
- Placeholder
- IsPassword
- BackgroundColor
feel free to add more
also, I didn't actually test binding... I did read somewhere that OnElementPropertyChanged
doesn't fire on a ViewRenderer
if you don't explicitly add the event hooks... that could have been a bug, I don't know. I just statically set these properties (for now).