我可以在 Xamarin Forms Shell 的标签栏上方添加静态视图吗? [英] Can I add a static view above the tabbar in Xamarin Forms Shell?

查看:43
本文介绍了我可以在 Xamarin Forms Shell 的标签栏上方添加静态视图吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Xamarin Forms Shell(iOS 和 Android)的标签栏上方添加一个自定义视图,以实现始终可见的音频播放器.

I want to add a custom view above the tabbar in Xamarin Forms Shell (iOS and Android) to implement an audio player that is always visible.

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

For Android I looked into this blog post about customizing the tabbar on Android (https://www.andrewhoefling.com/Blog/Post/xamarin-forms-shell-customizing-the-tabbar-android), and added an extra layout with id '@+id/bottomtab.view' to my customized 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 添加到布局中,但这不起作用.

In my custom ShellItemRenderer of my TabBar subclass I want to add the xaml to the layout, but that doesn't work.

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>

由于某种原因应用了外部网格的背景,就像您在屏幕截图中看到的那样,但没有显示内容.我不知道如何应用正确的尺寸来使网格和孩子们占据屏幕的整个宽度.

For some reason the background of the outer grid is applied, like you can see in the screenshot, but the contents are not shown. I don't know how to apply the correct dimensions to make the grid and the children take the full width of the screen.

截图

// 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, 0, width, height));
    
    nativeView.Layout(0, 0, width, height);

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

    nativeView.ForceLayout();
}

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

I like the idea to define the contents of the view in xaml to be able to setup the bindings and such. How can I render the view correctly in the layout?

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

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

更新 2020-11-12

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

I have changed my code to implement Leo's suggestion, but changed it to use the bottomtab.view layout in the android xml. (I use the framelayout bottomtab.tabbar.container for a kind of floating button, that works fine).

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

However, it looks like the width of the view above the tab bar is incorrect. In the screenshot you see that the Pink BoxView doesn't have a right side, it looks like the inner gridview (white background) is too wide. The bottom black border of the screenshot is the tabbar that I redacted.

截图

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

This is my definition of the extra view in xaml:

<Grid BackgroundColor="HotPink">

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

    </Grid>                
                
</Grid>

这是改编的SetupView方法

This is the adapted SetupView method

private void SetupTopView()
{
    var todoTabBar = (SearchTabBar)ShellItem;
    var height = 70;
    var width = (int)Resources.DisplayMetrics.WidthPixels;
    Rectangle size = new Rectangle(0, 0, width, 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 定义不正确?

Any suggestion to let it use the correct width? Or is my xaml definition incorrect?

推荐答案

您可以尝试以下方法:

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, 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);
 }

这篇关于我可以在 Xamarin Forms Shell 的标签栏上方添加静态视图吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆