微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以在Xamarin Forms Shell的选项卡上方添加静态视图吗?

如何解决我可以在Xamarin Forms Shell的选项卡上方添加静态视图吗?

我想在Xamarin Forms Shell(iOS和Android)的选项卡上方添加自定义视图,以实现始终可见的音频播放器。

对于Android,我浏览了有关在Android(https://www.andrewhoefling.com/Blog/Post/xamarin-forms-shell-customizing-the-tabbar-android)上自定义标签栏的博客文章,并将ID为'@ + id / bottomtab.view'的额外布局添加到了自定义的BottomTabLayout.axml中。

<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" />

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

            <LinearLayout
                android:orientation="horizontal"
                android:id="@+id/bottomtab.view"
                android:layout_width="match_parent"
                android:background="@drawable/abc_action_bar_item_background_material"
                android:layout_height="70dp" />

            <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>
    </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>

在我的TabBar子类的自定义ShellItemRenderer中,我想将xaml添加到布局中,但这不起作用。

using Xamarin.Forms;

namespace TodosSample.Controls
{
    public class TodoTabBar : TabBar
    {
        public Tab LargeTab { get; set; }

        public View View { get; set; }
    }
}

XAML

<c:TodoTabBar.View>
    <Grid BackgroundColor="#232026" Padding="10">
    <Grid BackgroundColor="PaleVioletRed">
    <Grid.RowDeFinitions>
        <RowDeFinition Height="*" />
    </Grid.RowDeFinitions>

    <Grid BackgroundColor="#092C33" Grid.Row="0">
        <Grid.ColumnDeFinitions>
            <ColumnDeFinition Width="60" />
            <ColumnDeFinition Width="*" />
            <ColumnDeFinition Width="60" />
        </Grid.ColumnDeFinitions>

        <Button BackgroundColor="IndianRed" Text="Click me" Clicked="Button_Clicked"/>

            <Grid Grid.Column="1" BackgroundColor="Yellow">
                <Label Text="Guy en Marinda" />
            </Grid>

            <Grid Grid.Column="2" WidthRequest="50" HeightRequest="50" BackgroundColor="Aqua" />


    </Grid>

</c:TodoTabBar.View>

由于某些原因,应用了外部网格的背景,如屏幕截图所示,但未显示内容。我不知道如何应用正确的尺寸来使网格和孩子们占据整个屏幕宽度。

Screenshot

// Rendering part in the custom TodoShellItemRenderer. This code is being called
private void SetupView()
{
    var todoTabBar = (TodoTabBar)ShellItem;

    var renderer = Platform.CreateRendererWithContext(todoTabBar.View,Context);
    renderer.Tracker.UpdateLayout();
    var nativeView = renderer.View;
    nativeView.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent,ViewGroup.LayoutParams.WrapContent);
    
    
    int width = ViewGroup.LayoutParams.MatchParent;
    int height = 70;
    todoTabBar.View.Layout(new Xamarin.Forms.Rectangle(0,width,height));
    
    nativeView.Layout(0,height);

    _view.RemoveAllViews();
    _view.AddView(nativeView);

    nativeView.ForceLayout();
}

我喜欢在xaml中定义视图内容的想法,以便能够设置绑定等。 如何在布局中正确呈现视图?

===============

更新2020-11-12

我更改了代码以实现Leo的建议,但更改为使用android xml中的bottomtab.view布局。 (我将framelayout bottomtab.tabbar.container用于一种浮动按钮,效果很好)。

但是,选项卡栏上方的视图宽度似乎不正确。在屏幕截图中,您可以看到Pink BoxView没有右侧,它看起来像内部的gridview(白色背景)太宽。 屏幕截图的底部黑色边框是我编辑的标签栏。

Screenshot

这是我对xaml中额外视图的定义:

<Grid BackgroundColor="HotPink">

    <BoxView BackgroundColor="Pink"  />
    <Grid BackgroundColor="White" Margin="5">

    </Grid>                
                
</Grid>

这是改编的SetupView方法

private void SetupTopView()
{
    var todoTabBar = (SearchTabBar)ShellItem;
    var height = 70;
    var width = (int)Resources.displayMetrics.WidthPixels;
    Rectangle size = new Rectangle(0,height);
    todoTabBar.Extraview.Layout(size);
    var renderer = Platform.CreateRendererWithContext(todoTabBar.Extraview,Context);
    renderer.Tracker.UpdateLayout();
    var nativeView = renderer.View;

    var layout = new FrameLayout(Context);
    layout.AddView(nativeView);
    var lp = new FrameLayout.LayoutParams(width,height * (int)Resources.displayMetrics.Density);
    _bottomView.Measure((int)MeasureSpecMode.Unspecified,(int)MeasureSpecMode.Unspecified);
    lp.BottomMargin = _bottomView.MeasuredHeight;

    layout.LayoutParameters = lp;
    _extraviewContainer.RemoveAllViews();
    _extraviewContainer.AddView(layout);
}

有没有建议让它使用正确的宽度?还是我的xaml定义不正确?

解决方法

您可以尝试以下操作:

public override Android.Views.View OnCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
    {
        var 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 TodoTabBar todoTabBar && todoTabBar.LargeTab != null)
            SetupView();

        return outerlayout;
    }

private void SetupView()
 {
        var todoTabBar = (TodoTabBar)ShellItem;
        var height = 70;
        var width = (int)Resources.DisplayMetrics.WidthPixels;
        Rectangle size = new Rectangle(0,width,height);
        todoTabBar.View.Layout(size);
        var renderer = Platform.CreateRendererWithContext(todoTabBar.View,Context);
        renderer.Tracker.UpdateLayout();
        var nativeView = renderer.View;
 
        var layout = new FrameLayout(Context);
        layout.AddView(nativeView);
        var lp = new FrameLayout.LayoutParams(width,height* (int)Resources.DisplayMetrics.Density);
        _bottomView.Measure((int)MeasureSpecMode.Unspecified,(int)MeasureSpecMode.Unspecified);
        lp.BottomMargin = _bottomView.MeasuredHeight;

        layout.LayoutParameters = lp;
        _shellOverlay.RemoveAllViews();
        _shellOverlay.AddView(layout);
 }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。