我想在 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>
由于某种原因,应用了外部网格的背景,就像您在屏幕截图中看到的那样,但没有显示内容。我不知道如何应用正确的尺寸来使网格和孩子占据屏幕的整个宽度。
// 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 中定义视图内容以便能够设置绑定等的想法。如何在布局中正确渲染视图?
================
2020-11-12 更新
我已更改代码以实现 Leo 的建议,但将其更改为使用 android xml 中的 bottomtab.view 布局。(我使用 framelayout bottomtab.tabbar.container 作为一种浮动按钮,效果很好)。
但是,标签栏上方的视图宽度看起来不正确。在屏幕截图中,您看到 Pink BoxView 没有右侧,看起来内部 gridview(白色背景)太宽了。屏幕截图的底部黑色边框是我编辑的标签栏。
这是我对 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, 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 定义不正确?