I am programmatically entering text into a bunch of Entry controls in a ContentPage. I don't want the keyboard to show since the user isn't supposed to type into them - the text comes from a different async service. But I do want the blinking cursor to show as visual feedback.
This is a common problem in Android land with everyone stating the same solutions (here and here).
So I have a custom renderer for the Entry control, which looks like this for Android:
[assembly: ExportRenderer (typeof (MyEntry), typeof (MyEntryRenderer_Android))] public class MyEntryRenderer_Android: EntryRenderer { protected override void OnElementChanged (ElementChangedEventArgs<Entry> e) { base.OnElementChanged (e); if (e.OldElement == null) { // **** this doesn't work InputMethodManager imm = (InputMethodManager)Context.GetSystemService(global::Android.Content.Context.InputMethodService); imm.HideSoftInputFromWindow(Control.WindowToken, HideSoftInputFlags.None); } } protected override void OnAttachedToWindow() { // **** this doesn't work either InputMethodManager imm = (InputMethodManager)Context.GetSystemService(global::Android.Content.Context.InputMethodService); imm.HideSoftInputFromWindow(Control.WindowToken, HideSoftInputFlags.None); base.OnAttachedToWindow(); } public override bool OnInterceptTouchEvent(MotionEvent e) { // **** this does work Control.RequestFocus(); if (UIControl.Instance.VoiceInputEnabled) { return true; } else { return false; } } }
You can see my attempts at preventing the keyboard in OnElementChanged
and OnAttachedToWindow
. They don't work, it still pops up when I programmatically set focus to the control. However, if the user clicks on the entry, that OnInterceptTouchEvent override is called and that does prevent the keyboard from showing.
BTW I have also tried this in my MainActivity.cs for Android:
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); this.Window.SetSoftInputMode(SoftInput.StateAlwaysHidden); //... }
Still no dice. How can prevent it from showing?
Posts
Hi, did you solve this? I created a workaround to fix this, it looks bad but it is the only way I found to accomplish that. Please, tell me if you found a "good" solution or if you want to see my solution, Xamarin support thinks it is a bug but still didnt fix it.
Hi @akevan
this.Window.SetSoftInputMode(SoftInput.StateAlwaysHidden);
this line works fine for me.
That works for Xamarin.Android, but not for an Entry Renderer in Xamarin Forms. It's confirmed that the functionality doesn't exist - https://bugzilla.xamarin.com/show_bug.cgi?id=27613.
In the meantime, I've written a custom renderer for my Entry control w/ a bindable text field.
Forms Code:
Android Renderer:
(it was doing funky recursive setting of text w/ two way binding, the _setFromTextInput flag is to deal with that)
I have used this
None of these prevent keyboard from showing. They show soft keyboard, then hide it which is even worse.
why all code duplication?
I think it could be written better
o, ok, I just thought maybe there is some code missing. It is also never detaching events, probably memory leak?
However, I still dont understand how is it suppose to prevent keyboard from showing. To me, all it does is hide it after the fact that it has been shown on both Click and FocusChange events. But I guess, it is good enough for your requirement.
Thanks anyways, I need to prevent soft keyboard from showing, not to hide it after it has been shown
4 lines...may less with resharper. Post some refactored code.
This hides keyboard entirely on Window. What if you have 2 Entries, one should have keyboard disabled, the other one should have it enabled. How to hide it on only that one particular Entry?
I think i found a sort of hack... but for me is ok...
Create custom entry renderer in android and...
Control.ShowSoftInputOnFocus = false;
Control.SetCursorVisible(false);
Control.InputType = InputTypes.Null;
This is not enough, because entry.Focus() show keyboard... I suggest you replace entry.Focus whit this: " entry.CursorPosition = entry.CursorPosition == 0 ? 1 : 0;"