rotorgames / Rg.Plugins.Popup

Xamarin Forms popup plugin
MIT License
1.15k stars 337 forks source link

Popup gets moved only when something is written and not when keyboard appears on Android 11 #677

Open czwinzscher opened 3 years ago

czwinzscher commented 3 years ago

šŸ› Bug Report

On Android 11, when opening a Popup with an Entry and then focusing the entry, the Popup doesn't get moved up when the keyboard appears. Only when you start typing something the Popup gets moved. When the keyboard gets dismissed the Popup also doesn't move back down. It's working as expected on Android 9 and 10.

Android Emulator - pixel_3_xl_r_11_0_-_api_30_5558 2021-06-30 08-45-56

Expected behavior

The Popup gets moved up when the keyboard appears so the Popup and the keyboard don't overlap. The Popup should move back down when the keyboard disappears.

Reproduction steps

<?xml version="1.0" encoding="utf-8" ?>
<popup:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:popup="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
             x:Class="PopupBug.MyPopupPage">
    <Grid HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" BackgroundColor="White" HeightRequest="300" WidthRequest="300">
        <Entry VerticalOptions="CenterAndExpand" />
    </Grid>
</popup:PopupPage>
using Rg.Plugins.Popup.Services;
using System;
using Xamarin.Forms;

namespace PopupBug
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, EventArgs e)
        {
            await PopupNavigation.Instance.PushAsync(new MyPopupPage());
        }
    }
}

Configuration

Version: 2.0.0.12

Platform:

simon10says commented 3 years ago

I'm also having this issue with Android 11. Any updates or workaround?

I've tried XF 4.8 and the latest 5.0, both able to replicate this issue on Android 11. However, both works fine on Android 10 and earlier.

simon10says commented 3 years ago

After looking at a similar issue and debugging with the sample demo to PopupPageRenderer.cs, it seems like with Android 11, the OnLayout() wasn't triggered the same as Android 10; and decoreView?.GetWindowVisibleDisplayFrame(visibleRect); captured before the keyboard is displayed.

My workaround is to listen to GlobalLayout event and do a RequestLayout() whenever the keyboard is shown/hidden. The steps are:

  1. Create a custom renderer
    
    using System;
    using Android.App;
    using Android.Content;
    using Android.Runtime;
    using Android.Views;
    using MyTest.Droid.Renderers;
    using MyTest.Xamarin.Controls;
    using Xamarin.Forms;

[assembly: ExportRenderer(typeof(PopUpBase), typeof(PopUpBaseRenderer))] namespace MyTest.Droid.Renderers { [Preserve(AllMembers = true)] public class PopUpBaseRenderer : Rg.Plugins.Popup.Droid.Renderers.PopupPageRenderer { private Android.Graphics.Rect LastVisibleRect;

    public PopUpBaseRenderer(Context context) : base(context) { }

    protected override void OnAttachedToWindow()
    {
        ViewTreeObserver.GlobalLayout += ViewTreeObserver_GlobalLayout;
        base.OnAttachedToWindow();
    }

    protected override void OnDetachedFromWindow()
    {
        ViewTreeObserver.GlobalLayout -= ViewTreeObserver_GlobalLayout;
        base.OnDetachedFromWindow();
    }

    private void ViewTreeObserver_GlobalLayout(object sender, EventArgs e)
    {
        Console.WriteLine($"global layout");

        try
        {
            var activity = (Activity?)Context;
            var decoreView = activity?.Window?.DecorView;
            var visibleRect = new Android.Graphics.Rect();
            decoreView?.GetWindowVisibleDisplayFrame(visibleRect);
            Console.WriteLine($"visible Rect: {visibleRect.FlattenToString()}");

            if (LastVisibleRect?.FlattenToString() != visibleRect.FlattenToString())
            {
                Console.WriteLine($"global layout RequestLayout");
                LastVisibleRect = visibleRect;
                this.RequestLayout();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

}

2. And PopUpBase is just the PopupPage:
```c#
public class PopUpBase : PopupPage {}

Briefly tested and seems to work

LuckyDucko commented 3 years ago

Hey @simon10says great work here.

I will try and give this a squiz as soon as possible, but in a more integrated way into the PopupRenderer.

akhilvs000 commented 2 years ago

Any update on the issue?

MNADEEMCH commented 2 years ago

@simon10says Thanks It's working fine now. I also facing the problem keyboard overlap on the Rg.Popup page but with your code it's working fine. Thanks again. Rg.Plugins.Popup (2.1.0) Xamarin.Forms (5.0.0.2337)

vikern22 commented 2 years ago

We're experiencing the same issue on Android 12 as well!

NiladriPadhy commented 1 year ago

Hey @simon10says great work here.

I will try and give this a squiz as soon as possible, but in a more integrated way into the PopupRenderer.

Working for me too. Thanks for sharing the solution.

PlaysafePP commented 2 months ago

Thankyou, your solution saved me a big headache as I really didn't know what to do next. In my case the popup was not redrawing when the keyboard was hidden. You solution addressed that for me :)