How to change ReturnKey on Keyboard in Xamarin Forms ?

Xamarin Forms it’s another world. It’s become simple when you already know the solution: Custom Renderer.

I’m using Xamarin Forms “portable” and XAML frontend with Android API 23.

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.

ReturnType.cs in PCL

public enum ReturnType
{
    Go,
    Next,
    Done,
    Send,
    Search
}

CustomEntry.cs in PCL

public class CustomEntry : Entry
{
    // Need to overwrite default handler because we cant Invoke otherwise
    public new event EventHandler Completed;

    public static readonly BindableProperty ReturnTypeProperty = BindableProperty.Create(
        nameof(ReturnType),
        typeof(ReturnType),
        typeof(CustomEntry),
        ReturnType.Done, 
        BindingMode.OneWay
    );

    public ReturnType ReturnType
    {
        get { return (ReturnType)GetValue(ReturnTypeProperty); }
        set { SetValue(ReturnTypeProperty, value); }
    }

    public void InvokeCompleted()
    {
        if (this.Completed != null)
            this.Completed.Invoke(this, null);
    }
}

CustomEntryRenderer.cs for Android

public class CustomEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        CustomEntry entry = (CustomEntry)this.Element;

        if(this.Control != null)
        {
            if(entry != null)
            {
                SetReturnType(entry);

                // Editor Action is called when the return button is pressed
                Control.EditorAction += (object sender, TextView.EditorActionEventArgs args) =>
                {
                    if (entry.ReturnType != ReturnType.Next)
                        entry.Unfocus();

                    // Call all the methods attached to custom_entry event handler Completed
                    entry.InvokeCompleted();
                };
            }
        }
    }

    private void SetReturnType(CustomEntry entry)
    {
        ReturnType type = entry.ReturnType;

        switch (type)
        {
            case ReturnType.Go:
                Control.ImeOptions = ImeAction.Go;
                Control.SetImeActionLabel("Go", ImeAction.Go);
                break;
            case ReturnType.Next:
                Control.ImeOptions = ImeAction.Next;
                Control.SetImeActionLabel("Next", ImeAction.Next);
                break;
            case ReturnType.Send:
                Control.ImeOptions = ImeAction.Send;
                Control.SetImeActionLabel("Send", ImeAction.Send);
                break;
            case ReturnType.Search:
                Control.ImeOptions = ImeAction.Search;
                Control.SetImeActionLabel("Search", ImeAction.Search);
                break;
            default:
                Control.ImeOptions = ImeAction.Done;
                Control.SetImeActionLabel("Done", ImeAction.Done);
                break;
        }
    }
}

CusomEntryRenderer.cs for iOS

public class CustomEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        CustomEntry entry = (CustomEntry)this.Element;

        if (this.Control != null)
        {
            if(entry != null)
            {
                SetReturnType(entry);

                Control.ShouldReturn += (UITextField tf) =>
                {
                    entry.InvokeCompleted();
                    return true;
                };
            }
        }
    }

    private void SetReturnType(CustomEntry entry)
    {
        ReturnType type = entry.ReturnType;

        switch (type)
        {
            case ReturnType.Go:
                Control.ReturnKeyType = UIReturnKeyType.Go;
                break;
            case ReturnType.Next:
                Control.ReturnKeyType = UIReturnKeyType.Next;
                break;
            case ReturnType.Send:
                Control.ReturnKeyType = UIReturnKeyType.Send;
                break;
            case ReturnType.Search:
                Control.ReturnKeyType = UIReturnKeyType.Search;
                break;
            case ReturnType.Done:
                Control.ReturnKeyType = UIReturnKeyType.Done;
                break;
            default:
                Control.ReturnKeyType = UIReturnKeyType.Default;
                break;
        }
    }
}

Usage

XAML file :

<renderer:CustomEntry x:Name="txtUsername" Text="Username" ReturnType="Next" /><renderer:CustomEntry x:Name="txtPassword" Text ="Password" IsPassword="true" ReturnType="Done" />

Code behind file:

txtUsername.Completed += (object sender, EventArgs e) => txtPassword.Focus();
txtPassword.Completed += (object sender, EventArgs e) => //Move to another page Output:    

4 Comments

  • Bidy July 13, 2017 Reply

    Thanks.

  • Marc February 23, 2018 Reply

    Top Post thank you

  • Daniel February 27, 2019 Reply

    This does not work for me on a real device for Android: SetImeActionLabel does not make the softkeyboard show the text but rather shows the specified icon.
    To show the specified icon, this code works!.
    To show the specified imeactionlabel, it wil only work on an android emulator.
    Still thx for the post, I am using it. Maybe there is no way to display text instead of an icon on Android?

    • Harshad Patel March 18, 2019 Reply

      Can you please tell me device name(model) I will try to my side same device check and try to fixing.

Leave a Reply

Read previous post:
Android supported HTML Tags : How to Parse String with HTML Tags

HTML support of TexView will add glossy look to your web app. You can't avoid html tags when you working...

Close