Reputation: 30216
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.
Upvotes: 7
Views: 9696
Reputation: 13
The key to prevent the virtual keyboard from appearing is to override the Focus() method of Entry and NOT call the base method. Otherwise it will always appear occasionally, regardless what you do. This has the additional benefit of simplifying the needed code since you automatically gain control over the appearance and disapperarnce of the virtual keyboard. I have not found any negative sideeffects of this approach so far.
I have created a sample control with full control over the virtual keyboard and a small app that shows the usage.
Since this question is asked in several forums I decided to rather write a detailed Readme attached to the project that explains all key points of the implementation instead of duplicating the explanation in several different forums. I hope that is okay. If not, please let me know.
The whole project is available here: https://github.com/UweReisewitz/XamarinAndroidEntry
Upvotes: 0
Reputation: 1697
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
Upvotes: 7
Reputation: 51571
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);
}
}
}
Upvotes: 3