#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.