maui
maui copied to clipboard
Soft Keyboard does not Pop Up when Entry View's Focus is set to True Programmatically
Description
When Focus is set to an Entry view programmatically (entryTest.Focus()), the cursor blinks in the edit field of the Entry view, but the soft keyboard does not pop up as it should until you physically touch the Entry view. In comparison to Xamarin Forms where the keyboard pops up when executing entryTest.Focus().
Also, entryTest.Focus() is ignored when placed in the OnAppearing Event.
Video demo of Maui App:
https://user-images.githubusercontent.com/101732760/162827580-c62e0530-9fa1-4f90-b744-90c37caeec57.mp4
Video demo of Xamarin Forms version:
https://user-images.githubusercontent.com/101732760/162827635-9904fcb9-7276-4eba-8d90-ac4c2c7019d9.mp4
XAML:
Code Behind:
Steps to Reproduce
- Create a new blank Maui app
- Add and Entry View and name it entryTest
- Add 2 Buttons and set Text to "Set Focus" and "Set Unfocus"
- In the Code behind for the 1st button add code entryTest.Focus()
- In the Code behind for the 2nd button add code enryTest.Unfocus()
- Run the App
- Click the Set Focus button.
- Notice the Entry field cursor blinks
- Notice the keyboard does not pop up
- Tap the Entry field.
- Notice the keyboard pops up.
Version with bug
Preview 14 (current)
Last version that worked well
Unknown/Other
Affected platforms
Android
Affected platform versions
Android 11
Did you find any workaround?
No
Relevant log output
No response
Verified this issue with Visual Studio Enterprise 17.2.0 Preview 2.1 [32317.152]. Repro on Android. Sample Project: 5983.zip
Still not working in GA. Is there a method, to show/hide the ENTRY keyboard manually?
I've encountered the same problem. But when I use "Entry" inside Grid instead of StackLayout, it works just fine. Entry and StackLayout don't get along yet.
Still not working in GA. Is there a method, to show/hide the ENTRY keyboard manually?
I've encountered a different problem. Keyboard is not hiding when unfocus entry. I made a wordaround in handler:
protected override void ConnectHandler(AppCompatEditText platformView)
{
base.ConnectHandler(platformView);
if (VirtualView is Entry entryControl)
entryControl.ObserveUnfocused().Subscribe(UnfocusedSubscription);
}
private void UnfocusedSubscription(FocusEventArgs args)
{
if (!args.IsFocused)
{
InputMethodManager inputMethodManager = (InputMethodManager)global::Android.App.Application.Context.GetSystemService(global::Android.Content.Context.InputMethodService);
inputMethodManager.HideSoftInputFromWindow(PlatformView.WindowToken, HideSoftInputFlags.None);
}
}
I use own observable method, but you can use events.
Many thanks marcoablanco. That looks interesting and a real benefit, compared to XF Forms. It seems, that i should investigate some time, understanding the handler architecture in Maui.
Still not working in GA. Is there a method, to show/hide the ENTRY keyboard manually?
I've encountered a different problem. Keyboard is not hiding when unfocus entry. I made a wordaround in handler:
protected override void ConnectHandler(AppCompatEditText platformView) { base.ConnectHandler(platformView); if (VirtualView is Entry entryControl) entryControl.ObserveUnfocused().Subscribe(UnfocusedSubscription); } private void UnfocusedSubscription(FocusEventArgs args) { if (!args.IsFocused) { InputMethodManager inputMethodManager = (InputMethodManager)global::Android.App.Application.Context.GetSystemService(global::Android.Content.Context.InputMethodService); inputMethodManager.HideSoftInputFromWindow(PlatformView.WindowToken, HideSoftInputFlags.None); } }
I use own observable method, but you can use events.
Can you give me more context how to use this in a sample app. I cannot figure out where I put these code of yours... I've found https://github.com/davidortinau/CustomRendererSample example. But this does not work with the current MAUI version (I get a cast exception when I start the example as is). thanks
Still not working in GA. Is there a method, to show/hide the ENTRY keyboard manually?
I've encountered a different problem. Keyboard is not hiding when unfocus entry. I made a wordaround in handler:
protected override void ConnectHandler(AppCompatEditText platformView) { base.ConnectHandler(platformView); if (VirtualView is Entry entryControl) entryControl.ObserveUnfocused().Subscribe(UnfocusedSubscription); } private void UnfocusedSubscription(FocusEventArgs args) { if (!args.IsFocused) { InputMethodManager inputMethodManager = (InputMethodManager)global::Android.App.Application.Context.GetSystemService(global::Android.Content.Context.InputMethodService); inputMethodManager.HideSoftInputFromWindow(PlatformView.WindowToken, HideSoftInputFlags.None); } }
I use own observable method, but you can use events.
Can you give me more context how to use this in a sample app. I cannot figure out where I put these code of yours... I've found https://github.com/davidortinau/CustomRendererSample example. But this does not work with the current MAUI version (I get a cast exception when I start the example as is). thanks
I created a EntryHandler for Maui Entry control in Android folder. You can see more about Handler in https://docs.microsoft.com/dotnet/maui/user-interface/handlers/customize
Adding
<Entry Text="HELLO" Focused="Entry_Focused" Unfocused="Entry_Unfocused" />
and running it on a Android OS never triggers Entry Unfocused, with a standard maui template when tapping outside the entrybox.
Also the custom handlers does not seem to contain the following code in, or im doing it wrong: .ObserveUnfocused().Subscribe(UnfocusedSubscription);
So im not sure how you were able to run that code @marcoablanco
It just dont fire on unfocused.
Defocus_issue.zip Added a sample
Defocus_issue.zip Added a sample
Your handler is not registered. I added to MauiProgram and works.
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
#if ANDROID
.ConfigureMauiHandlers(handlers => handlers.AddHandler<Microsoft.Maui.Controls.Entry, Survey.Handlers.EntryHandler>())
#endif
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
return builder.Build();
I changed a little bit your handler
public partial class EntryHandler : Microsoft.Maui.Handlers.EntryHandler
{
protected override void ConnectHandler(AppCompatEditText platformView)
{
base.ConnectHandler(platformView);
platformView.FocusChange += PlatformView_FocusChange;
}
protected override void DisconnectHandler(AppCompatEditText platformView)
{
base.DisconnectHandler(platformView);
platformView.FocusChange -= PlatformView_FocusChange;
}
private void PlatformView_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs args)
{
if (args.HasFocus)
{
InputMethodManager inputMethodManager = (InputMethodManager)global::Android.App.Application.Context.GetSystemService(global::Android.Content.Context.InputMethodService);
inputMethodManager.ShowSoftInput(PlatformView, ShowFlags.Forced);
}
else
{
InputMethodManager inputMethodManager = (InputMethodManager)global::Android.App.Application.Context.GetSystemService(global::Android.Content.Context.InputMethodService);
inputMethodManager.HideSoftInputFromWindow(PlatformView.WindowToken, HideSoftInputFlags.None);
}
}
}
Thank you for tweaking the sample, looks much better!
Im still struggling to make the sample work, it does not lose focus. Meaning, when you have a entry and you click outside the entry or click a button, the entry should lose focus and stop blinking which it does not in a simple .NET maui start template. That means as far as i can understand that this code will not run as the focuschange event will never fire when you click outside the entrybox.
I hope there are things here i dont understand .. :)
Use something like this to have the old XF tap outside of the entry defocus in the mainactivity.
I think it works, might need some adjustments.
public override bool DispatchTouchEvent(MotionEvent ev)
{
if (ev.Action == MotionEventActions.Up)
{
var v = Window.CurrentFocus;
if (v is EditText)
{
Rect outRect = new Rect();
v.GetGlobalVisibleRect(outRect);
if (!outRect.Contains(new Rect(ev.RawX, ev.RawY, 1, 1)))
{
v.ClearFocus();
InputMethodManager imm = (InputMethodManager)GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(v.WindowToken, 0);
}
}
}
return base.DispatchTouchEvent(ev);
}
Surprised to see ! It isn't working till today.
This definitely needs a fix
I've encountered the same problem. But when I use "Entry" inside Grid instead of StackLayout, it works just fine. Entry and StackLayout don't get along yet.
Changing my stack layout for a grid doesn't work, when invoking Focus()
the software keyboard does not show. This is still a bug.
Quick Solution : Make Entry , Editor or Any thirdparty controls IsEnabled = false then Entry.UnFocus() to hide the key board and Again don't forget to make IsEnabled property to true as soon as the task is completed. :)
This same bug report appears to apply to the Editor control as well.
Quick Solution : Make Entry , Editor or Any thirdparty controls IsEnabled = false then Entry.UnFocus() to hide the key board and Again don't forget to make IsEnabled property to true as soon as the task is completed. :)
The only optiion that works for me. Thank you ;)
The problem that the Sofkeyboard does not close automatically once touched somewhere outside of the keyboard, is caused by the fact that the Android ViewGroup does not clear the focus anymore in MAUI. In XF the ViewGroup always cleared the focus correctly on touch events. In MAUI it seem it was forgotten to be implemented? XF: https://github.com/xamarin/Xamarin.Forms/blob/a31ddcfe18a0490f7e0fccccfc6e879c2f309485/Xamarin.Forms.Platform.Android/PlatformRenderer.cs#L68
Here's some code you can use to interact with the keyboard for the time being
https://github.com/PureWeen/ShanedlerSamples/tree/main/ShanedlerSamples/Keyboard
If you call "ShowKeyboard" there's no need to call "Focus" when using this code.
to this day it still doesn't work
Does not seem to fire public bool OnSingleTapUp(MotionEvent e) if you remove the scrollview from the sample.
Try adding this code to the Focused event of the Entry. Resolved the issue of the keyboard not showing up in my MAUI app when running on Surface Pro 9.
CoreInputView.GetForCurrentView().TryShow(CoreInputViewKind.Keyboard);
Found from https://stackoverflow.com/questions/39618127/programmatically-open-on-screen-keyboard-in-uwp
Try adding this code to the Focused event of the Entry. Resolved the issue of the keyboard not showing up in my MAUI app when running on Surface Pro 9.
CoreInputView.GetForCurrentView().TryShow(CoreInputViewKind.Keyboard);
Found from https://stackoverflow.com/questions/39618127/programmatically-open-on-screen-keyboard-in-uwp
I can confirm this works when called from Windows platform code, I came across the same link as @relecon and chanced my arm. Added a more detailed explanation here:
(https://github.com/microsoft/microsoft-ui-xaml/issues/6291?fbclid=IwAR0qlccdWand42VzTFhUhleJuv_t-jaTkO1igI3B1rrvUh0k6cgXIpHDW9g#issuecomment-1378649391)
I added a mapper here that you can copy to add this behavior for android.
One thing to note is that if your intention is to open the keyboard you should use
KeyboardManager.ShowKeyboard not Focus
Using Focus
to influence the Keyboard
has always felt like a hack to me in general.
Try this solution
`private async void OnShowKeyboardTapped(object sender, EventArgs e) { EntryInput.Focus(); await Task.Delay(100); // Important to add delay here Helpers.KeyboardVisibility(true); }
private async void OnHideKeyboardTapped(object sender, EventArgs e) { Helpers.KeyboardVisibility(false); }
private void KeyboardVisibility(bool StateFocus) { #if ANDROID if (Platform.CurrentActivity.CurrentFocus != null) { if (StateFocus) { Platform.CurrentActivity.ShowKeyboard(Platform.CurrentActivity.CurrentFocus); } else { Platform.CurrentActivity.HideKeyboard(Platform.CurrentActivity.CurrentFocus); Platform.CurrentActivity.CurrentFocus.ClearFocus(); } } #endif } `