Open dinobu opened 5 years ago
When #4384 is merged it will make this possible for a custom renderer on Android.
That said, it may be worth exploring adding something like a ShowSoftKeyboardOnFocus
property to InputView
with the default set to true
.
When #4384 is merged it will make this possible for a custom renderer on Android.
That said, it may be worth exploring adding something like a
ShowSoftKeyboardOnFocus
property toInputView
with the default set totrue
.
I was asking for Xamarin.Forms, not Android. We need this for Android, iOS, and definitely UWP as that is the most problematic as it turns out. Xamarin.EnableKeyboardHelperEffect suggested by @masonyc is not supporting UWP and it not preventing but rather hiding keyboard once opened on Android and iOs which is not that great considering that you get popups that then go away.
perhaps this effect can solve your problem for the moment?https://github.com/masonyc/Xamarin.EnableKeyboardEffect
@masonyc Looks like it could, thanks. Looks like only code is required on iOS FinishedLaunching while on android there is no code, XAML itself is sufficient? Also, why do you have comment "Write here" in FinishedLaunching?
@masonyc Looks like it could, thanks. Looks like only code is required on iOS FinishedLaunching while on android there is no code, XAML itself is sufficient? Also, why do you have comment "Write here" in FinishedLaunching?
In iOS, we need that line to init the effect but in android, it does itself. "Write here" comment just a reminder that you don't forget that line
@masonyc Looks like it could, thanks. Looks like only code is required on iOS FinishedLaunching while on android there is no code, XAML itself is sufficient? Also, why do you have comment "Write here" in FinishedLaunching?
In iOS, we need that line to init the effect but in android, it does itself. "Write here" comment just a reminder that you don't forget that line
Thanks I will give it a try. I'd suggest updating wiki to clarify that for others. Much appreciated.
@masonyc I created 3 new issues
When #4384 is merged it will make this possible for a custom renderer on Android. That said, it may be worth exploring adding something like a
ShowSoftKeyboardOnFocus
property toInputView
with the default set totrue
.I was asking for Xamarin.Forms, not Android. We need this for Android, iOS, and perhaps UWP
That is a pull request against Xamarin Forms, not Xamarin Android.
When #4384 is merged it will make this possible for a custom renderer on Android. That said, it may be worth exploring adding something like a
ShowSoftKeyboardOnFocus
property toInputView
with the default set totrue
.I was asking for Xamarin.Forms, not Android. We need this for Android, iOS, and perhaps UWP
That is a pull request against Xamarin Forms, not Xamarin Android.
True it is against Xamarin.Forms,but the reply was only for Android if you read it. My response is that we need solution for iOS, Android and UWP
@masonyc Looks like it could, thanks. Looks like only code is required on iOS FinishedLaunching while on android there is no code, XAML itself is sufficient? Also, why do you have comment "Write here" in FinishedLaunching?
In iOS, we need that line to init the effect but in android, it does itself. "Write here" comment just a reminder that you don't forget that line
Unfortunately, this solution has 2 problems:
Also, the keyboard is prevented only when Entry is rendered, meaning once you load the view. But if you click on say a popup message to close it, you then have to call Focus to focus on that field and programmatic calls to Focus will not prevent but show, then hide keyboard resulting in strange behavior where keyboard keeps showing briefly for apparent no reason.
perhaps this effect can solve your problem for the moment?https://github.com/masonyc/Xamarin.EnableKeyboardEffect
Unfortunately no. I have been using it but we have issues with it, mainly lack of UWP support.
Any progress on this recommendation?
I only this functionality on Android. I have found that using a custom renderer and setting ShowSoftInputOnFofus to false works when I tap on the entry, but if I call Entry.Focus() then it shows the keyboard. Is this a bug or expected behavior? It would be nice to have it be consistent.
@samhouts can you answer my question above? I am using a scanner device and when I call Entry.Focus I do not want the keyboard to show up.
@DanielGlick45 Exact same situation here. Did you find a solution?
@stavroaudi I did not. I am just ignoring the issue for now until it is fixed
I only this functionality on Android. I have found that using a custom renderer and setting ShowSoftInputOnFofus to false works when I tap on the entry, but if I call Entry.Focus() then it shows the keyboard. Is this a bug or expected behavior? It would be nice to have it be consistent.
I have a similar problem. The problem is that Entry.Focus () forcibly opens SoftKeyboard. My decision, when I get a new barcode, I do a defocus on the page and get it again, but with a native control that SoftKeyboard does not call. I understand the need for focus through clearing the Entry text. On the Page, when I get a new barcode
MessagingCenter.Subscribe<App, string>(this, "Barcode", async (sender, barcode) =>
{
if (!IsBusy)
{
quantityEntry.Unfocus();
quantityEntry.Text = "";
quantityEntry.Text = "1";
}
});
On the new renderer
public class SelectedEntryRenderer : EntryRenderer
{
public SelectedEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
//if (this.Control != null)
//{
// Control.SetPadding(10, 0, 0, 15);
// Control.InputType = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagSigned | Android.Text.InputTypes.NumberFlagDecimal;
// Control.TextAlignment = Android.Views.TextAlignment.Center;
//}
if (e.NewElement != null)
{
((SelectedEntry)e.NewElement).PropertyChanging += OnPropertyChanging;
((SelectedEntry)e.NewElement).TextChanged += SelectedEntryRenderer_TextChanged;
}
if (e.OldElement != null)
{
((SelectedEntry)e.OldElement).PropertyChanging -= OnPropertyChanging;
((SelectedEntry)e.OldElement).TextChanged -= SelectedEntryRenderer_TextChanged;
}
this.Control.ShowSoftInputOnFocus = false;
if (e.OldElement == null)
{
var nativeEditText = (global::Android.Widget.EditText)Control;
nativeEditText.SetSelectAllOnFocus(true);
nativeEditText.RequestFocus();
nativeEditText.SelectAll();
}
}
private void SelectedEntryRenderer_TextChanged(object sender, Xamarin.Forms.TextChangedEventArgs e)
{
if (string.IsNullOrEmpty(e.OldTextValue) && !string.IsNullOrEmpty(e.NewTextValue))
{
var nativeEditText = (global::Android.Widget.EditText)Control;
nativeEditText.RequestFocus(); //got a focus again without SoftKeyboard
nativeEditText.SelectAll();
}
}
private void OnPropertyChanging(object sender, Xamarin.Forms.PropertyChangingEventArgs propertyChangingEventArgs)
{
if (propertyChangingEventArgs.PropertyName == VisualElement.IsFocusedProperty.PropertyName)
{
// fully dismiss the soft keyboard
InputMethodManager imm = (InputMethodManager)this.Context.GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(this.Control.WindowToken, 0);
var nativeEditText = (global::Android.Widget.EditText)Control;
nativeEditText.SelectAll();
}
}
}
Any progress on this recommendation? Any workaround ? I find those posts : https://github.com/UweReisewitz/XamarinAndroidEntry https://github.com/masonyc/Xamarin.KeyboardHelper
But have issues with MVVM pattern, when use MessagingCenter to auto focus Entry. We can't build product with use off SDK codebarre scanner because the app was used by different devices..
I think best workaround was this : https://github.com/masonyc/Xamarin.KeyboardHelper I'm going to implement this on my project and provide feed back essentialy on Entry.Focus provided by the callback in MessagingCenter.
Thank in advance.
@samhouts can you answer my question above? I am using a scanner device and when I call Entry.Focus I do not want the keyboard to show up.
Exact same situation here. Did you find a solution?
@sanpas Any news?
Prevent native keyboard to popup on Android and iOS is only possible with customer renderers. Works reliable on our side. No idear about UWP (not needed yet).
On iOS EntryRenderer do basically set Control.InputView = null;
More dedailed idear for iOS:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Element.ClassId == yourCustomKeyboardOrScannerEntry)
{
if (e.NewElement != null)
{
// disables text drag-and-drop features (prevents us from crashes and issue when drag-drop-released on entry)
if (Control.TextDragInteraction != null) Control.TextDragInteraction.Enabled = false;
// do not auto-focus and open keyboard when view with entry loads
Control.ResignFirstResponder();
Control.AllowsEditingTextAttributes = false;
Control.KeyboardType = UIKeyboardType.NumbersAndPunctuation;
Control.LayoutMargins = new UIEdgeInsets(0, 0, 0, 0);
// hides caret (cursor) thumbnail
Control.TintColor = UIColor.Clear;
Control.InputView = null;
//Control.InputView = SetupYourCustomKeyboard();
UIMenuController.SharedMenuController.SetMenuVisible(false, false);
// removes the shortcut bar from text entry (copy & paste bar), otherwise it is shown
// on top of virtual keyboard or also if hardware keyboard is attached on E.g. iPadPro
Control.InputAssistantItem.LeadingBarButtonGroups = null;
Control.InputAssistantItem.TrailingBarButtonGroups = null;
// custom keyboard apple HIG: https://developer.apple.com/design/human-interface-guidelines/ios/extensions/custom-keyboards/
// Hiding softkeyboard if Apple HW keyboard or 3rd party Bluetooth keyboard is attached is not yet possible
// see also: http://www.openradar.appspot.com/17690744 & https://stackoverflow.com/questions/5019471/ipad-detecting-external-keyboard
// or https://gist.github.com/patridge/8984934#file-gistfile1-cs
}
}
}
On Android EntryRenderer do basically hide per default softkeyboard with EditText.ShowSoftInputOnFocus = false; and additonaly hide nasty soft keyboard always on touch event (pops up on rare cases, some old/slow devices).
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
EditText.HorizontalScrollBarEnabled = false; // do not show scrollbar on loading
// do not show fullscreen input mode + keyboard on landscape focused entry
Control.ImeOptions = (ImeAction)ImeFlags.NoExtractUi; // set keyboard size according to UI
if (Element.ClassId == yourCustomKeyboardOrScannerEntry)
{
if (e.NewElement != null)
{
//CreateHiddenCustomKeyboard();
EditText.HorizontalScrollBarEnabled = false; // do not show scrollbar on loading
// use of ClassText so that Bluetooth Keyboard decimal comma in E.g. DE-UICulture works
// never use InputTypes.Null cause this will result in invisible Caret (Cursor)
EditText.InputType = InputTypes.ClassText;
EditText.SetTextIsSelectable(true);
EditText.SetSelectAllOnFocus(true);
EditText.Touch += OnEntryTouch;
EditText.ShowSoftInputOnFocus = false;
}
// dispose control
if (e.OldElement != null)
{
EditText.Touch -= OnEntryTouch;
}
}
}
private void OnEntryTouch(object sender, TouchEventArgs e)
{
CloseNativeKeyboard();
EditText.OnTouchEvent(e.Event);
}
private void CloseNativeKeyboard()
{
//close native keyboard if some native element is focused in background
var imm = (InputMethodManager)context.GetSystemService(Context.InputMethodService)!;
imm.HideSoftInputFromWindow(EditText.WindowToken, 0);
}
Hey, is there a solution for this problem? I am also facing this behaviour with my barcode scanner.
I found a Solution Use Editor instead of Entry and use the TextChanged with a special Character as Suffix from the Scanner
I found a Solution Use Editor instead of Entry and use the TextChanged with a special Character as Suffix from the Scanner
HI. Can you explain what you have done? I have the sam problem with scanner. Thanks
Hey,
public class ScanEditor : Editor
{
}
Add this to ContentView or ContentPage
xmlns:local="clr-namespace:_NAMESPACE_.CustomComponent"
<local:ScanEditor x:Name="ScannerEditor"
Placeholder="Number"
PlaceholderColor="Gray"
TextChanged="ScanEditor_TextChanged"/>
using Android.Content;
using Android.Views.InputMethods;
// Path to ScanEditor class
using _NAMESPACE_.CustomComponent;
using _NAMESPACE_.Droid;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ScanEditor), typeof(ScanEditorRenderer))]
namespace _NAMESPACE_.Droid
{
public class ScanEditorRenderer : EditorRenderer
{
public ScanEditorRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
((ScanEditor)e.NewElement).PropertyChanging += OnPropertyChanging;
}
if (e.OldElement != null)
{
((ScanEditor)e.OldElement).PropertyChanging -= OnPropertyChanging;
}
// Disable the Keyboard on Focus
Control.ShowSoftInputOnFocus = false;
}
private void OnPropertyChanging(object sender, PropertyChangingEventArgs propertyChangingEventArgs)
{
// Check if the view is about to get Focus
if (propertyChangingEventArgs.PropertyName == VisualElement.IsFocusedProperty.PropertyName)
{
try
{
// incase if the focus was moved from another Entry
// Forcefully dismiss the Keyboard
InputMethodManager imm = (InputMethodManager)Context.GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(Control.WindowToken, 0);
}
catch (Exception ex)
{
_ = ex;
}
}
}
}
}
To scan a number with my scanner, i set the SUFFIX of the my scanner to a !
private void ScanEditor_TextChanged(object sender, TextChangedEventArgs e)
{
Editor entry = (Editor)sender;
// Check if Number contains !
if (e.NewTextValue.Contains("!"))
{
try
{
// Read Number
string number = e.NewTextValue.Split('!')[0].Trim();
// Do your Stuff with the number
// e.g. Trigger Custom Event
ScanFinished(sender, new ScanEventArgs(number));
}
catch (Exception ex)
{
_ = ex;
}
// Reset Text
entry.Text = "";
}
}
I hope this solves your problem. If there are further questions, don't hesitate to ask me and please excuse my poor english skills :-)
Hi thanks for your help. I develop a small app for reading barcodes.
But keyboard keeps appearing and veey annoying.
I will try your solution.
Thanks
On Mon, Mar 28, 2022, 05:31 SmartSquareAZ @.***> wrote:
Hey, First of all I created a class which inherits from Editor:
public class ScanEditor : Editor {
}
Usage in XAML:
Add this to ContentView or ContentPage
xmlns:local="clr-namespace:NAMESPACE.CustomComponent"
<local:ScanEditor x:Name="ScannerEditor" Placeholder="Number" PlaceholderColor="Gray" TextChanged="ScanEditor_TextChanged"/>
After that, I created a custom Renderer for Android (No need for IOs in my project):
using Android.Content; using Android.Views.InputMethods; // Path to ScanEditor class using NAMESPACE.CustomComponent; using NAMESPACE.Droid; using System; using Xamarin.Forms; using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ScanEditor), typeof(ScanEditorRenderer))] namespace NAMESPACE.Droid { public class ScanEditorRenderer : EditorRenderer { public ScanEditorRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e) { base.OnElementChanged(e); if (e.NewElement != null) { ((ScanEditor)e.NewElement).PropertyChanging += OnPropertyChanging; } if (e.OldElement != null) { ((ScanEditor)e.OldElement).PropertyChanging -= OnPropertyChanging; } // Disable the Keyboard on Focus Control.ShowSoftInputOnFocus = false; } private void OnPropertyChanging(object sender, PropertyChangingEventArgs propertyChangingEventArgs) { // Check if the view is about to get Focus if (propertyChangingEventArgs.PropertyName == VisualElement.IsFocusedProperty.PropertyName) { try { // incase if the focus was moved from another Entry // Forcefully dismiss the Keyboard InputMethodManager imm = (InputMethodManager)Context.GetSystemService(Context.InputMethodService); imm.HideSoftInputFromWindow(Control.WindowToken, 0); } catch (Exception ex) { _ = ex; } } } }
}
To scan a number with my scanner, i set the SUFFIX of the my scanner to a ! To read the number of the Input I used the TextChanged Event of Editor (Which I could use because my class inherits from Editor):
private void ScanEditor_TextChanged(object sender, TextChangedEventArgs e) { Editor entry = (Editor)sender; // Check if Number contains ! if (e.NewTextValue.Contains("!")) { try { // Read Number string number = e.NewTextValue.Split('!')[0].Trim(); // Do your Stuff with the number // e.g. Trigger Custom Event ScanFinished(sender, new ScanEventArgs(number)); } catch (Exception ex) { _ = ex; } // Reset Text entry.Text = ""; } }
I hope this solves your problem. If there are further questions, don't hesitate to ask me and please excuse my poor english skills :-)
— Reply to this email directly, view it on GitHub https://github.com/xamarin/Xamarin.Forms/issues/4555#issuecomment-1080173565, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGGVRX3R6QGX5OTIEFV65FDVCEYY5ANCNFSM4GGZ5VRQ . You are receiving this because you commented.Message ID: <xamarin/Xamarin. @.***>
Prevent native keyboard to popup on Android and iOS is only possible with customer renderers. Works reliable on our side. No idear about UWP (not needed yet).
On iOS EntryRenderer do basically set Control.InputView = null;
More dedailed idear for iOS:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) { base.OnElementChanged(e); if (Element.ClassId == yourCustomKeyboardOrScannerEntry) { if (e.NewElement != null) { // disables text drag-and-drop features (prevents us from crashes and issue when drag-drop-released on entry) if (Control.TextDragInteraction != null) Control.TextDragInteraction.Enabled = false; // do not auto-focus and open keyboard when view with entry loads Control.ResignFirstResponder(); Control.AllowsEditingTextAttributes = false; Control.KeyboardType = UIKeyboardType.NumbersAndPunctuation; Control.LayoutMargins = new UIEdgeInsets(0, 0, 0, 0); // hides caret (cursor) thumbnail Control.TintColor = UIColor.Clear; Control.InputView = null; //Control.InputView = SetupYourCustomKeyboard(); UIMenuController.SharedMenuController.SetMenuVisible(false, false); // removes the shortcut bar from text entry (copy & paste bar), otherwise it is shown // on top of virtual keyboard or also if hardware keyboard is attached on E.g. iPadPro Control.InputAssistantItem.LeadingBarButtonGroups = null; Control.InputAssistantItem.TrailingBarButtonGroups = null; // custom keyboard apple HIG: https://developer.apple.com/design/human-interface-guidelines/ios/extensions/custom-keyboards/ // Hiding softkeyboard if Apple HW keyboard or 3rd party Bluetooth keyboard is attached is not yet possible // see also: http://www.openradar.appspot.com/17690744 & https://stackoverflow.com/questions/5019471/ipad-detecting-external-keyboard // or https://gist.github.com/patridge/8984934#file-gistfile1-cs } } }
On Android EntryRenderer do basically hide per default softkeyboard with EditText.ShowSoftInputOnFocus = false; and additonaly hide nasty soft keyboard always on touch event (pops up on rare cases, some old/slow devices).
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) { base.OnElementChanged(e); EditText.HorizontalScrollBarEnabled = false; // do not show scrollbar on loading // do not show fullscreen input mode + keyboard on landscape focused entry Control.ImeOptions = (ImeAction)ImeFlags.NoExtractUi; // set keyboard size according to UI if (Element.ClassId == yourCustomKeyboardOrScannerEntry) { if (e.NewElement != null) { //CreateHiddenCustomKeyboard(); EditText.HorizontalScrollBarEnabled = false; // do not show scrollbar on loading // use of ClassText so that Bluetooth Keyboard decimal comma in E.g. DE-UICulture works // never use InputTypes.Null cause this will result in invisible Caret (Cursor) EditText.InputType = InputTypes.ClassText; EditText.SetTextIsSelectable(true); EditText.SetSelectAllOnFocus(true); EditText.Touch += OnEntryTouch; EditText.ShowSoftInputOnFocus = false; } // dispose control if (e.OldElement != null) { EditText.Touch -= OnEntryTouch; } } } private void OnEntryTouch(object sender, TouchEventArgs e) { CloseNativeKeyboard(); EditText.OnTouchEvent(e.Event); } private void CloseNativeKeyboard() { //close native keyboard if some native element is focused in background var imm = (InputMethodManager)context.GetSystemService(Context.InputMethodService)!; imm.HideSoftInputFromWindow(EditText.WindowToken, 0); }
@dinobu I think this is what you need; And for UWP, you can add something like below in your CustomRenderer:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// This should avoid keyboard display on programatic focus
this.Control.PreventKeyboardDisplayOnProgrammaticFocus = true;
Control.GotFocus += (sender, args) =>
{
AttemptToForceKeyboardToHide(Control);
};
Control.TextChanged += (sender, args) =>
{
if (Control.FocusState != FocusState.Unfocused)
{
AttemptToForceKeyboardToHide(Control);
}
};
}
}
private void AttemptToForceKeyboardToHide(FormsTextBox control)
{
try
{
var inputPane = InputPane.GetForUIContext(control.UIContext);
// This should hide keyboard quickly enough on UWP.
var keyboardShowSuccess = inputPane?.TryHide();
if (keyboardShowSuccess == null || !keyboardShowSuccess.Value)
{
Console.WriteLine("Attempt to force Keyboard to show failed on Windows.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
You may also want to look at this: https://stackoverflow.com/questions/10636635/disable-keyboard-on-edittext Hope that helps
Description
Support to prevent soft keyboard on Entry field for Android, iOS, and UWP head projects in Xamarin.Forms.
Currently, Entry field in Xamarin.Forms provides no functionality to prevent soft keyboard from showing up entirely. There are solution out there that will hide it but they make things even worse since now you have keyboard popping up briefly, then disappearing from the screen.
It feels like having a way to disable keyboard from showing up entirely on an Entry field makes sense. For example, I make my own buttons, that resemble keyboard. Tapping on each of these, puts some characters in the Entry field without showing keyboard but only when Entry field receives focus.
Another example, scanning with external barcode scanners into a field when it has focus only. Here also makes no sense to show keyboard.
Steps to Reproduce
Expected Behavior
It would be nice to be able to disable keyboard from showing up entirely on an Entry field focus. We need this for all 3 platforms in Xamarin.Forms, on UWP, iOS and Android
Actual Behavior
This is currently impossible to do. There are solution that hide keyboard (using renderers or other methods) which makes it even worse since keyboard shows briefly, then hides. In my example on scanning above, this solution makes it ridiculous.