Наложение оболочки форм Xamarin

#c# #xamarin.forms #xamarin.android

Вопрос:

Мне нужен совет. Я пытаюсь создать свою собственную оболочку рендеринга ShellOverlay, которая заполняет все пространство дисплея, см. Рисунок, это работает в Android10, но не работает в Android 11.

Кто — то должен знать, где может быть ошибка.

Здесь, на картинке, содержимое ShellOverlay заполнено по всему экрану. Содержимое находится как в строке состояния, так и в панели навигации

Android 10:

введите описание изображения здесь

Android 11: Содержимое ShellOverlay не перекрывается через строку состояния

введите описание изображения здесь

MainActivity.cs

  if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
 {
     Window.AddFlags(WindowManagerFlags.LayoutNoLimits);
     Window?.SetFlags(WindowManagerFlags.LayoutNoLimits, WindowManagerFlags.LayoutNoLimits);
 }
 

ShellOverlay renderers

 public class CustomShellRenderer : ShellRenderer
{
    public CustomShellRenderer(Context context) : base(context)
    {
    }

    protected override IShellItemRenderer CreateShellItemRenderer(ShellItem shellItem)
    {
        return new CustomShellItemRenderer(this);
    }
   
}

public class CustomShellItemRenderer : ShellItemRenderer
{
    FrameLayout shellOverlay;
    View outerlayout;
    BottomNavigationView bottomView;
    IVisualElementRenderer viewRenderer;

    public CustomShellItemRenderer(IShellContext shellContext) : base(shellContext)
    {
    }

    public override Android.Views.View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        outerlayout = base.OnCreateView(inflater, container, savedInstanceState);
        bottomView = outerlayout.FindViewById<BottomNavigationView>(Resource.Id.bottomtab_tabbar);
        shellOverlay = outerlayout.FindViewById<FrameLayout>(Resource.Id.bottomtab_tabbar_container);

        if (ShellItem is ShellOverlay overlay amp;amp; overlay.Content != null)
            SetupOverlay();

        return outerlayout;
    }

    private void SetupOverlay()
    {
        var overlay = (ShellOverlay)ShellItem;

        bottomView.Measure((int)MeasureSpecMode.Unspecified, (int)MeasureSpecMode.Unspecified);

        outerlayout.Measure((int)MeasureSpecMode.Unspecified, (int)MeasureSpecMode.Unspecified);

        shellOverlay.RemoveAllViews();
        shellOverlay.AddView(ConvertFormsToNative(overlay.Content,
            new Xamarin.Forms.Rectangle(0, 0, Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Width / Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density, Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Height / Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density)));
    }

    public override void OnConfigurationChanged(Configuration newConfig)
    {
        base.OnConfigurationChanged(newConfig);

        SetupOverlay();
    }

    private View ConvertFormsToNative(Xamarin.Forms.View view, Xamarin.Forms.Rectangle size)
    {
        viewRenderer = Platform.CreateRendererWithContext(view, Context);
        var viewGroup = viewRenderer.View;
        viewRenderer.Tracker.UpdateLayout();

        if (view.HeightRequest > 0)
            size.Height = view.HeightRequest;

        var layoutParams = new ViewGroup.LayoutParams((int)(size.Width * Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density), (int)(size.Height * Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density));
        viewGroup.LayoutParameters = layoutParams;
        view.Layout(size);
        viewGroup.Layout(0, 0, (int)view.Width, (int)view.Height);
        return viewGroup;
    }
}
 

layout/ BottomTabLayout.xml

 <?xml version="1.0" encoding="utf-8" ?>  

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@ id/bottomtab.navarea"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="fill"
        android:layout_weight="1" />
    
    <com.google.android.material.bottomnavigation.BottomNavigationView 
        android:id="@ id/bottomtab.tabbar"
        android:theme="@style/Widget.Design.BottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

<FrameLayout
    android:id="@ id/bottomtab.tabbar.container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal|bottom" />
    
</FrameLayout>
 

Контрольная накладка

 public class ShellOverlay : ShellItem
{
    public View Content { get; set; }
}
 

AppShell.xaml

 <Shell xmlns="http://xamarin.com/schemas/2014/forms" 
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:shellOverlay="clr-namespace:ShellOverLayTest.Views.Controls.ShellOverlay;assembly=ShellOverLayTest"
   Title="ShellOverLayTest"
   x:Class="ShellOverLayTest.AppShell"
   Shell.FlyoutBehavior="Disabled"
   Shell.TabBarIsVisible="False"
   Shell.NavBarIsVisible="False">

<shellOverlay:ShellOverlay x:Name="Overlay">
    <shellOverlay:ShellOverlay.Content>
        <Grid x:Name="GridRoot"  
              VerticalOptions="FillAndExpand"
              HorizontalOptions="FillAndExpand" 
              BackgroundColor="Red">

        </Grid>
    </shellOverlay:ShellOverlay.Content>
</shellOverlay:ShellOverlay>
 

AppShell.cs

  public AppShell()
 {
    InitializeComponent();
    Overlay.Items.Add(new ShellContent { Route = nameof(MainPage), ContentTemplate = new DataTemplate(typeof(MainPage)) });
 }
 

Большое спасибо

Комментарии:

1. Я проверил тот же код с вашим. Это работает на моей стороне, чтобы заполнить весь экран. Пожалуйста, проверьте мой скриншот. imgur.com/KYgA2MT Не могли бы вы предоставить более подробную информацию для воспроизведения?

2. Это правда, что он работает на эмуляторе. Я протестировал его на физическом телефоне Realme GT 5G с интерфейсом 2.0, а также на Samsung Galaxy S21 5G. В оболочке XF на обоих телефонах содержимое страницы не отображалось в полноэкранном режиме. Я также попробовал это с классической оболочкой, где страница отображалась не на всем дисплее, а затем с пустым окном, где содержимое страницы уже отображалось на всем дисплее, поэтому я думаю, что ошибка будет где-то в оболочке XF. Вот почему я создал тему на XF github.com/xamarin/Xamarin. Формы/вопросы/14716

3. У меня нет конкретного устройства для повторной проверки. Давайте проследим за #14716 этим на GitHub.