代码之家  ›  专栏  ›  技术社区  ›  Patrik

Xamarin形成贝壳覆盖层

  •  0
  • Patrik  · 技术社区  · 4 年前

    我需要一些建议。我正在尝试创建自己的shell渲染 ShellOverlay 这占据了整个显示空间,请看图片,这在Android10中有效,但在Android11中不起作用。

    有人会知道错误在哪里。

    在这张图片中,ShellOverlay内容被填充到整个屏幕上。内容位于状态栏和导航栏下

    安卓10:

    enter image description here

    安卓11: ShellOverlay的内容不会通过状态栏重叠

    enter image description here

    主要活动。反恐精英

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

    ShellOverlay渲染器

    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 && 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;
        }
    }
    

    布局/底部布局。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。反恐精英

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

    谢谢

    0 回复  |  直到 4 年前
    推荐文章