Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide softkeyboard in Xamarin

How do I hide the softkeyboard for showing up when focusing an Entry in Xamarin.forms portable forms project? I assume we have to write platform specific renderers for that, but the following does not work:

I create my own entry subclass:

public class MyExtendedEntry : Entry
{
}

and then in the xamarin.android project my renderer:

public class MyExtendedEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            new Handler().Post(delegate
            {
                var imm = (InputMethodManager)Control.Context.GetSystemService(Context.InputMethodService);
                var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);
            });
        }
    }
}

The OnElementChanged is called as expected and when using Handler.Post() I also get a WindowToken instead of null. Sadly the return value from HideSoftInputFromWindow is always false and the softkeyboard still turns up when clicking on the Entry.

like image 433
Voo Avatar asked Mar 03 '15 15:03

Voo


2 Answers

OnElementChanged is called whenever the view is initialized and attached to the view. What you want to do is to hide the keyboard when the entry is clicked, so you should add an event handler to FocusChange to the Control.

Example:

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            Control.Click += (sender, evt) => {
                new Handler().Post(delegate
                    {
                        var imm = (InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
                        var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);

                        Console.WriteLine(result);
                    });
            };

            Control.FocusChange += (sender, evt) => {
                new Handler().Post(delegate
                    {
                        var imm = (InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
                        var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);

                        Console.WriteLine(result);
                    });
            };
        }
    }

Update: Combined answer from @Vikram

Update: Added Click event handler

like image 68
Alex Lau Avatar answered Nov 12 '22 12:11

Alex Lau


Note: I am not versed in Xamarin.

In my experience, using imm.HideSoftInputFromWindow(Control.WindowToken, 0) immediately after the control receives focus produces dodgy results, even when using Post. I have had success using PostDelayed instead. The delay I use is 500ms.

Give this a try:

public class MyExtendedEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            new Handler().PostDelayed(delegate
            {
                var imm = (InputMethodManager)Control.Context.GetSystemService(Context.InputMethodService);
                var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);
            }, 500L);
        }
    }
}
like image 3
Vikram Avatar answered Nov 12 '22 13:11

Vikram