Change return to be next/done key in Xamarin Forms Shared Project

后端 未结 4 1798
北海茫月
北海茫月 2020-12-13 18:53

Is it possible to change the text in the \'return\' key on the keyboard to be either \'next\' or \'done\'? I have a login form with username and password. I want the return

4条回答
  •  萌比男神i
    2020-12-13 19:34

    A custom EntryRenderer can handle changing the keyboard return key description.

    • iOS : UITextField has a ReturnKeyType property that you can set to a preassigned list (see UIReturnType enum).

    • Android : EntryEditText has a ImeOptions property that controls what the "Action" button on the keyboard does and a SetImeActionLabel method that you can use to set any text string for it.

    Usage Example of the custom Entry/EntryRenderer:

    new EntryExt {
        Text = "Next Key",
        ReturnKeyType = ReturnKeyTypes.Next
    },
    new EntryExt {
        Text = "Done Key",
        ReturnKeyType = ReturnKeyTypes.Done
    }
    

    A Xamarin.Forms custom Entry class:

    namespace YourNameSpaceHere
    {
        public class EntryExt : Entry
        {
            public const string ReturnKeyPropertyName = "ReturnKeyType";
    
            public EntryExt() { }
    
            public static readonly BindableProperty ReturnKeyTypeProperty = BindableProperty.Create(
                propertyName: ReturnKeyPropertyName,
                returnType: typeof(ReturnKeyTypes),
                declaringType: typeof(EntryExt),
                defaultValue: ReturnKeyTypes.Done);
    
            public ReturnKeyTypes ReturnKeyType
            {
                get { return (ReturnKeyTypes)GetValue(ReturnKeyTypeProperty); }
                set { SetValue(ReturnKeyTypeProperty, value); }
            }
        }
    
        // Not all of these are support on Android, consult EntryEditText.ImeOptions
        public enum ReturnKeyTypes : int
        {
            Default,
            Go,
            Google,
            Join,
            Next,
            Route,
            Search,
            Send,
            Yahoo,
            Done,
            EmergencyCall,
            Continue
        }
    }
    

    iOS custom EntryRenderer:

    [assembly: ExportRenderer(typeof(Entry), typeof(EntryExtRenderer_iOS))]
    namespace KeyboardDone.iOS
    {
        public class EntryExtRenderer_iOS : EntryRenderer
        {
            public EntryExtRenderer_iOS() { }
    
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if ((Control != null) && (e.NewElement != null))
                    Control.ReturnKeyType = (e.NewElement as EntryExt).ReturnKeyType.GetValueFromDescription();
            }
    
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if (e.PropertyName == EntryExt.ReturnKeyPropertyName)
                {
                    D.WriteLine($"{(sender as EntryExt).ReturnKeyType.ToString()}");
                    Control.ReturnKeyType = (sender as EntryExt).ReturnKeyType.GetValueFromDescription();
                }
            }
        }
    
        public static class EnumExtensions
        {
            public static UIReturnKeyType GetValueFromDescription(this ReturnKeyTypes value)
            {
                var type = typeof(UIReturnKeyType);
                if (!type.IsEnum) throw new InvalidOperationException();
                foreach (var field in type.GetFields())
                {
                    var attribute = Attribute.GetCustomAttribute(field,
                        typeof(DescriptionAttribute)) as DescriptionAttribute;
                    if (attribute != null)
                    {
                        if (attribute.Description == value.ToString())
                            return (UIReturnKeyType)field.GetValue(null);
                    }
                    else
                    {
                        if (field.Name == value.ToString())
                            return (UIReturnKeyType)field.GetValue(null);
                    }
                }
                throw new NotSupportedException($"Not supported on iOS: {value}");
            }
        }
    }
    

    Android custom EntryRenderer:

    [assembly: ExportRenderer(typeof(Entry), typeof(EntryExtRenderer_Droid))]
    namespace KeyboardDone.Droid
    {
        public class EntryExtRenderer_Droid : EntryRenderer
        {
            public EntryExtRenderer_Droid() { }
    
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if ((Control != null) && (e.NewElement != null))
                {
                    var entryExt = (e.NewElement as EntryExt);
                    Control.ImeOptions = entryExt.ReturnKeyType.GetValueFromDescription();
                    // This is hackie ;-) / A Android-only bindable property should be added to the EntryExt class 
                    Control.SetImeActionLabel(entryExt.ReturnKeyType.ToString(), Control.ImeOptions);
                }
            }
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if (e.PropertyName == EntryExt.ReturnKeyPropertyName)
                {
                    var entryExt = (sender as EntryExt);
                    Control.ImeOptions = entryExt.ReturnKeyType.GetValueFromDescription();
                    // This is hackie ;-) / A Android-only bindable property should be added to the EntryExt class 
                    Control.SetImeActionLabel(entryExt.ReturnKeyType.ToString(), Control.ImeOptions);
                }
            }
    
        }
        public static class EnumExtensions
        {
            public static ImeAction GetValueFromDescription(this ReturnKeyTypes value)
            {
                var type = typeof(ImeAction);
                if (!type.IsEnum) throw new InvalidOperationException();
                foreach (var field in type.GetFields())
                {
                    var attribute = Attribute.GetCustomAttribute(field,
                        typeof(DescriptionAttribute)) as DescriptionAttribute;
                    if (attribute != null)
                    {
                        if (attribute.Description == value.ToString())
                            return (ImeAction)field.GetValue(null);
                    }
                    else
                    {
                        if (field.Name == value.ToString())
                            return (ImeAction)field.GetValue(null);
                    }
                }
                throw new NotSupportedException($"Not supported on Android: {value}");
            }
        }
    }
    

提交回复
热议问题