MobileBlazorBindings icon indicating copy to clipboard operation
MobileBlazorBindings copied to clipboard

Virtual keyboard goes on top of input without option of scrolling

Open arivera12 opened this issue 5 years ago • 31 comments

I am able to scroll the page on regular browser but on BlazorWebView is not possible.

Screenshot_20201106-234922

arivera12 avatar Nov 07 '20 03:11 arivera12

On Android you can collapse the keyboard by pressing the Back button or usually there's some other keyboard-close action you can take. But I think I've seen this before and it's quite annoying. I haven't looked into how to fix it but I'm sure there must be a way.

Eilon avatar Nov 09 '20 17:11 Eilon

Yup it quite annoying, pressing the back button collapse the keyboard but once you focus an input it gets on top of the input again, this need to be workarounded somehow, its makes a form navigation and entry quite imposible, not sure how ios behaves on this one...

arivera12 avatar Nov 09 '20 19:11 arivera12

Oh so in this case you want the input to be focused but the keyboard is hiding it? So ideally the input would "scroll up" a bit at least temporarily?

Eilon avatar Nov 09 '20 20:11 Eilon

Having scrolling capabilities can be considered a fix, but the way this should work is once I focus an input, keyboard should position below the working/focused input.

arivera12 avatar Nov 09 '20 20:11 arivera12

In that screenshot I shared page has no scrolling capabilities, on regular mobile browser it has scrolling capabilities so we should behave like regular mobile browsers do.

arivera12 avatar Nov 09 '20 20:11 arivera12

Oh so in this case you want the input to be focused but the keyboard is hiding it? So ideally the input would "scroll up" a bit at least temporarily?

Yes, is hiding it and is on top of it without scrolling capabilities

arivera12 avatar Nov 09 '20 20:11 arivera12

I think this issue should be considered a bug because it makes any form with no way to fill them without looking the current focused input. I am not able to see the password field on that login form when it's focused...

arivera12 avatar Nov 09 '20 20:11 arivera12

Yeah I agree it's a bug I'm just not sure where the bug is. Ideally apps shouldn't have to do much to support this because it's an extremely common scenario. But is it an issue in Mobile Blazor Bindings? In Xamarin.Forms? Somewhere else?

Eilon avatar Nov 09 '20 20:11 Eilon

I think the bug resides MBB on the BlazorWebView component. It's needs to react to any focused input.

arivera12 avatar Nov 09 '20 20:11 arivera12

Hmmm take a look of this... https://www.xamarinhelp.com/accommodate-on-screen-keyboard-xamarin-forms/

arivera12 avatar Nov 09 '20 20:11 arivera12

Oh well that looks easy 😄

Eilon avatar Nov 09 '20 20:11 Eilon

There is a bug with android it's seems...

arivera12 avatar Nov 09 '20 20:11 arivera12

Not sure if the shared link may help or resolves this issues but it's seems to be related somehow.

arivera12 avatar Nov 09 '20 20:11 arivera12

Related

https://forums.xamarin.com/discussion/87176/windowsoftinputmode-doesnt-work-in-xamarin-forms-android

arivera12 avatar Nov 09 '20 20:11 arivera12

Hi. @arivera12 , the way I fixed that was adjusting the keyboard size with this code:

Android: On the share project in the App.cs class:

Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

It looks like this: image

If you can notice in yellow I add the name space Xamarin.Forms to avoid conflict with Xamarin.Forms.PlatformConfiguration.AndroidSpecific.Application, that because the UseWindowSoftInputModeAdjust is an extension in AndroidSpecific.

iOS: Install package Xam.Plugins.Forms.KeyboardOverlap

Add in AppDelegate inside FinishedLaunching method, the line:

KeyboardOverlapRenderer.Init();

Hope that can help you!!

juanjfrancisco avatar Nov 11 '20 23:11 juanjfrancisco

@juanjfrancisco I will give it a try

arivera12 avatar Nov 12 '20 13:11 arivera12

@juanjfrancisco it works partially but after losing the input focus the windows doesn't resize back and leave blank space as show on the screenshot Screenshot_20210120-130532

arivera12 avatar Jan 20 '21 17:01 arivera12

Before adding new issue, looked for similar bugs and I found this.

I am also experiencing the same issue and when I tried the soft input mode adjust, The screen did not resize back as @arivera12 specified above.

Will there be a fix to this in the near future? Is there any workaround that we can use by the time we have the absolute solution?

idylmz avatar Jan 29 '21 13:01 idylmz

Hi folks, it's not clear to me if there's anything that Mobile Blazor Bindings needs to do or if it's a more general Xamarin/Xamarin.Forms thing, or if it's just a general Android (or other platform) thing. Does anyone know if it's specific to Mobile Blazor Bindings, or would this exact issue happen in any other Xamarin.Forms-based application? If it's more general, we should make sure there is an issue in the appropriate repo.

Eilon avatar Jan 29 '21 21:01 Eilon

@Eilon it's not clear for me also where it resides.

What @juanjfrancisco proposed works but when the keyboard hides I think the BlazorWebView supposes to resizes back an fit the original window size which it doesn't happens and leaves that blank space on the bottom.

And yes it's an android issue I had tested ios and it's ok.

arivera12 avatar Jan 29 '21 21:01 arivera12

@arivera12 thank for the info. The BlazorWebView is a bit complex in terms of how it handles interaction with the native WebView but it doesn't have any logic for resizing/moving things. So maybe it should have some logic like that, or maybe there's an issue in Xamarin.Forms and how it handles things.

Do we have any idea whether it's the size of the Xamarin.Forms control, the native Android WebView, or something else? Does this same issue happen in a plain Xamarin.Forms app with a regular WebView?

Eilon avatar Jan 29 '21 21:01 Eilon

Let me do a quick xamarin.forms app with some inputs and see how it behaves on android.

arivera12 avatar Jan 29 '21 21:01 arivera12

@Eilon

First test without

Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

Xamarin.Forms and BlazorWebView behaves exactly, keyboard goes on top of inputs without scrolling option.

Seconds test including

Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

On Xamarin.Forms keyboard has scrolling option and resize back once the keyboard hides.

On BlazorWebView keyboard has scrolling option but doesn't resize back leaving that blank space below once the keyboard hides.

arivera12 avatar Jan 29 '21 21:01 arivera12

Note:

I did test under the conditions of native web view control and regular xamarin input controls and blazorwebview.

arivera12 avatar Jan 29 '21 21:01 arivera12

@arivera12 @Eilon I found simple solution!

Method Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize); - have bugs on different android devices, and we disabled that function

Solution:

  1. For Example:
<div style="margin-bottom:@(margin)px">
<input type="text" @bind="something"  @onfocusin="OnFocusIn" @onfocusout="OnFocusOut" />
</div>
@code {
 private double margin;
 private bool makeMargin;
}
  1. Handle focus input with two methods. Get keyboard height (on android), e.g 280~300 px
void OnFocusIn(FocusEventArgs e)
   {
       if (Device.RuntimePlatform == Device.Android) // on ios works fine 
       {
           makeMargin = true;
           SetMargin();
       }
   }

   void OnFocusOut(FocusEventArgs e)
   {
       if (Device.RuntimePlatform == Device.Android) // on ios works fine 
       {
           makeMargin = false;
           SetMargin();
       }
   }

   void SetMargin()
   {
       if (makeMargin)
       {
           margin = 280;
       }
       else
       {
           margin = 0;
       }
       StateHasChanged();
   }
  1. Profit! And you can scroll blazor content when virtual keyboard showing

But you can get real virtual anrdoid keyboard height, like using DependencyService

Work example: https://stackoverflow.com/a/63492647/15333425

Remark:

IKeyboardHelper keyboardHelper = DependencyService.Get<IKeyboardHelper>(); 
        keyboardHelper.KeyboardHeightChanged.Subscribe(x => margin = Math.Ceiling(x));
        if (margin == 0)
        {
            await Task.Delay(500);
        }

If you want auto scroll when focus input (virtual keboard showing):

  1. Add div with id into blazor view, like focusDiv
<div style="margin-bottom:@(margin)px">
<input type="text" @bind="something"  @onfocusin="OnFocusIn" @onfocusout="OnFocusOut" />
</div>
<div id="focusDiv"></div>
  1. Change OnFocusIn method name to OnFocusInAsync, add some delay and invoke js function
async Task OnFocusInAsync(FocusEventArgs e)
   {
       if(Device.RuntimePlatform == Device.Android)
       {
           makeMargin = true;
           SetMargin();
           await Task.Delay(500);
           await JsRuntime.InvokeVoidAsync("scrollToInvisibleDiv", "focusBtn");
       }
   }
  1. Add JS function :
window.scrollToInvisibleDiv = (div) => {
    document.getElementById(div).scrollIntoView();
}

Slevya avatar Mar 18 '21 10:03 Slevya

This looks like more like a dirty workaround rather than a solution. I did something like this before but was dirty workaround IMO. It's not a good workaround unless we don't need to listen to all inputs focus and blur events over blazor side. This needs to be worked on the android side inside the blazorwebview. For a decent workaround I think this should manage over pure JavaScript rather than over blazor side.

arivera12 avatar Mar 18 '21 16:03 arivera12

@Eilon I found a good and simple working solution doing 2 things!

@Slevya can you try and test my work around?

I moved the BlazorWebView out from it's main container:

Changed this:

<ContentView>
    <StackLayout>
        <BlazorWebView VerticalOptions="LayoutOptions.FillAndExpand">
            <HybridSolutionTemplate.WebUI.App />
        </BlazorWebView>
    </StackLayout>
</ContentView>

To this:

<BlazorWebView VerticalOptions="LayoutOptions.FillAndExpand">
    <HybridSolutionTemplate.WebUI.App />
</BlazorWebView>

And added this line of code in the App.cs inside the xamarin project after var host = hostBuilder.Build();

Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

After that keyboard works perfectly I did few test on pages with pages with large forms and works just perfectly!

Source Modifications Screenshots

Main.razor image

App.cs image

It's seem the issue it's what I expected at the beginning the containers are not resizing well for some reason but at least this makes BlazorWebView work properly over android without any issues.

I still think this should be considered a bug for all reasons mentioned above.

arivera12 avatar Mar 22 '21 20:03 arivera12

@arivera12 This definetely works for Android, thanks!

Haven't tried with iPhone though. But I didn't have any issues with iPhones.

idylmz avatar Mar 23 '21 10:03 idylmz

@arivera12 This definetely works for Android, thanks!

Haven't tried with iPhone though. But I didn't have any issues with iPhones.

Thanks for the feedback!

arivera12 avatar Mar 23 '21 15:03 arivera12

@Eilon I found a good and simple working solution doing 2 things!

@Slevya can you try and test my work around?

I moved the BlazorWebView out from it's main container:

Changed this:

<ContentView>
    <StackLayout>
        <BlazorWebView VerticalOptions="LayoutOptions.FillAndExpand">
            <HybridSolutionTemplate.WebUI.App />
        </BlazorWebView>
    </StackLayout>
</ContentView>

To this:

<BlazorWebView VerticalOptions="LayoutOptions.FillAndExpand">
    <HybridSolutionTemplate.WebUI.App />
</BlazorWebView>

And added this line of code in the App.cs inside the xamarin project after var host = hostBuilder.Build();

Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

After that keyboard works perfectly I did few test on pages with pages with large forms and works just perfectly!

Source Modifications Screenshots

Main.razor image

App.cs image

It's seem the issue it's what I expected at the beginning the containers are not resizing well for some reason but at least this makes BlazorWebView work properly over android without any issues.

I still think this should be considered a bug for all reasons mentioned above.

Tested on Anrdoid 8.0 (Samsung Galaxy A3 - real device), Nexus 5x Api 28 (android 9.0), Pixel 2 Q 10.0 (Api 29 Anrdoid 10.0). Works perfectly

Slevya avatar Mar 23 '21 19:03 Slevya