Xamarin Android 底部导航未显示在所有屏幕上
Xamarin Android bottom navigation not displaying on all screens
我已经在 Xamarin 中实现了底部导航 Android。单击底部导航栏中的每个图标时,我需要显示不同的屏幕。
我在 main activity 中工作正常,但在底部导航项目的选择上,如何在保持底部导航可见的同时显示新屏幕。
单击底部导航栏中的图标时,我再次设置内容,因此底部导航栏隐藏(因为加载了没有底部导航栏的新内容)。
我对 Xamarin 的经验很少Android所以不知道是否有布局页面之类的东西可以容纳底部导航。
我了解了 Framelayout 和 fragments,但不知道如何使用底部导航来实现。任何帮助将不胜感激。
底栏添加到第一个 activity。如果您更改 activity,选择时底栏会消失。
您需要添加带片段的视图分页器才能实现
你可以看看这个tutorial
你也可以看到这段代码sample
由于您正在更改 Activity 的 ContentView,它正在消失:
您可以按照以下步骤实现 BottomNavigationView:
由于我们正在处理片段,我将把我的 MainActivity 基础 class 更改为 Android.Support.V7.App.AppCompatActivity
,是的,我们将使用 Android 支持库 V4.Since 我正在处理 Fragments,我会将我的 MainActivity 基础 class 更改为 Android.Support.V7.App.AppCompatActivity
,是的,我们将使用 Android 支持库V4 和 V7。查看此博客是否有 understanding support libraries
public class MainActivity : Android.Support.V7.App.AppCompatActivity
为我们的 MainActivity 创建一个布局,我们将添加一个 FrameLayout 来保存我们的 Fragment、一个 ViewPager 和一个来自 Android.Support.Design 库的 BottomNavigationView,如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_navigation" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/bottom_navigation" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="start"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
app:menu="@menu/navigation_main" />
</RelativeLayout>
也为 Fragment 创建一个布局。我会用一个图标和一个标签来保持简单,你可以在这里保留你想要的任何东西:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:src="@drawable/abc_ic_star_black_48dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Fragment"
android:textAlignment="center"
android:textSize="@dimen/abc_text_size_display_1_material"
android:layout_below="@id/imageView"
android:layout_centerVertical="false" />
</RelativeLayout>
让我们进入底部导航。首先,我们需要 BottomNavigationView 的导航项(选项卡),我们将为此添加一个导航菜单。
navigation_main.xml //xml 文件名
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:orderInCategory="0"
android:id="@+id/menu_genres"
android:enabled="true"
android:title="Genres"
android:icon="@drawable/tab_genres"
app:showAsAction="always" />
<item
android:orderInCategory="1"
android:id="@+id/menu_titles"
android:enabled="true"
android:title="Titles"
android:icon="@drawable/tab_titles"
app:showAsAction="always" />
<item
android:orderInCategory="2"
android:id="@+id/menu_stream"
android:enabled="true"
android:title="Stream"
android:icon="@drawable/tab_stream"
app:showAsAction="always" />
<item
android:orderInCategory="3"
android:id="@+id/menu_showtimes"
android:enabled="true"
android:title="Showtimes"
android:icon="@drawable/tab_showtimes"
app:showAsAction="always" />
</menu>
注意 orderInCategory
,这是选项卡项从左到右的顺序。
好的,现在我们已经将我们将要使用的视图放在一起。现在让我们进入 BottomNavigationView。
在 MainActivity 中获取 BottomNavigationView 并进行设置。
bottomNavigationView= FindViewById<BottomNavigationView>(Resource.Id.bottom_navigation);
此外,如果选项卡超过 3 个,BottomNavigationView 会隐藏标签。所以,让我们改变一下。将此辅助方法添加到您的代码中,并在像这样设置 BottomNavigationView 时调用它,
RemoveShiftMode(_navigationView);//Below the FindViewById
private void RemoveShiftMode(BottomNavigationView view) // a Method in the Activity
{
var menuView = (BottomNavigationMenuView) view.GetChildAt(0);
try
{
var shiftingMode = menuView.Class.GetDeclaredField("mShiftingMode");
shiftingMode.Accessible = true;
shiftingMode.SetBoolean(menuView, false);
shiftingMode.Accessible = false;
for (int i = 0; i < menuView.ChildCount; i++)
{
var item = (BottomNavigationItemView)menuView.GetChildAt(i);
item.SetShiftingMode(false);
// set checked value, so view will be updated
item.SetChecked(item.ItemData.IsChecked);
}
} catch (System.Exception ex) {
System.Diagnostics.Debug.WriteLine((ex.InnerException??ex).Message);
}
}
现在,我们应该没事了。就是这样。我们完成了 BottomNavigationView 的设置。我们还没有为每个选项卡实现片段,所以点击选项卡不会显示任何内容。我们将在 ViewPager 中呈现片段。
现在,让我们设置 ViewPager。一、适配器,
public class ViewPagerAdapter : FragmentPagerAdapter
{
Fragment[] _fragments;
public ViewPagerAdapter(FragmentManager fm, Fragment[] fragments) : base(fm)
{
_fragments = fragments;
}
public override int Count => _fragments.Length;
public override Fragment GetItem(int position) => _fragments[position];
}
然后,ViewPager,
// find the view
_viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
// set the adapter
_viewPager.Adapter = new ViewPagerAdapter(SupportFragmentManager, _fragments);
这就是设置 ViewPager 的原因。
当用户在 ViewPager 视图之间滑动时,ViewPager.PageSelected 事件被触发。同样,当用户点击 BottomNavigationView 中的选项卡(导航菜单项)时,将触发 BottomNavigationView.NavigationItemSelected 事件。我们必须 link 这两个事件才能使 BottomNavigationView 和 ViewPager 同步跳舞。以下是我们将如何做。
如下声明 BottomNavigationView 和 ViewPager 的事件处理程序,
// wireup the page selection event
_viewPager.PageSelected += ViewPager_PageSelected;
// wire up the selection event
_navigationView.NavigationItemSelected += NavigationView_NavigationItemSelected;
当ViewPager页面被选中时,我们通知BottomNavigationView,反之亦然。像这样,
private void ViewPager_PageSelected(object sender, ViewPager.PageSelectedEventArgs e)
{
var item = _navigationView.Menu.GetItem(e.Position);
_navigationView.SelectedItemId = item.ItemId;
}
void NavigationView_NavigationItemSelected(object sender,
BottomNavigationView.NavigationItemSelectedEventArgs e)
{
_viewPager.SetCurrentItem(e.Item.Order, true);
}
就是这样。现在 BottomNavigationView 和 ViewPager 正在显示所选 fragment/page/tab 并通过平滑过渡相互更新。
最后一件事,为这些选项卡加载片段。
void InitializeTabs()
{
_fragments = new Fragment[] {
TheFragment.NewInstance("Genres", "tab_genres"),
TheFragment.NewInstance("Titles", "tab_titles"),
TheFragment.NewInstance("Stream", "tab_stream"),
TheFragment.NewInstance("Showtimes", "tab_showtimes")
};
}
我已经在 Xamarin 中实现了底部导航 Android。单击底部导航栏中的每个图标时,我需要显示不同的屏幕。 我在 main activity 中工作正常,但在底部导航项目的选择上,如何在保持底部导航可见的同时显示新屏幕。 单击底部导航栏中的图标时,我再次设置内容,因此底部导航栏隐藏(因为加载了没有底部导航栏的新内容)。
我对 Xamarin 的经验很少Android所以不知道是否有布局页面之类的东西可以容纳底部导航。
我了解了 Framelayout 和 fragments,但不知道如何使用底部导航来实现。任何帮助将不胜感激。
底栏添加到第一个 activity。如果您更改 activity,选择时底栏会消失。
您需要添加带片段的视图分页器才能实现
你可以看看这个tutorial
你也可以看到这段代码sample
由于您正在更改 Activity 的 ContentView,它正在消失:
您可以按照以下步骤实现 BottomNavigationView:
由于我们正在处理片段,我将把我的 MainActivity 基础 class 更改为
Android.Support.V7.App.AppCompatActivity
,是的,我们将使用 Android 支持库 V4.Since 我正在处理 Fragments,我会将我的 MainActivity 基础 class 更改为Android.Support.V7.App.AppCompatActivity
,是的,我们将使用 Android 支持库V4 和 V7。查看此博客是否有 understanding support librariespublic class MainActivity : Android.Support.V7.App.AppCompatActivity
为我们的 MainActivity 创建一个布局,我们将添加一个 FrameLayout 来保存我们的 Fragment、一个 ViewPager 和一个来自 Android.Support.Design 库的 BottomNavigationView,如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/fragment_content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/bottom_navigation" /> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/bottom_navigation" /> <android.support.design.widget.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="56dp" android:layout_gravity="start" android:layout_alignParentBottom="true" android:background="@android:color/white" app:menu="@menu/navigation_main" /> </RelativeLayout>
也为 Fragment 创建一个布局。我会用一个图标和一个标签来保持简单,你可以在这里保留你想要的任何东西:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageView" android:src="@drawable/abc_ic_star_black_48dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Fragment" android:textAlignment="center" android:textSize="@dimen/abc_text_size_display_1_material" android:layout_below="@id/imageView" android:layout_centerVertical="false" /> </RelativeLayout>
让我们进入底部导航。首先,我们需要 BottomNavigationView 的导航项(选项卡),我们将为此添加一个导航菜单。
navigation_main.xml //xml 文件名
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:orderInCategory="0" android:id="@+id/menu_genres" android:enabled="true" android:title="Genres" android:icon="@drawable/tab_genres" app:showAsAction="always" /> <item android:orderInCategory="1" android:id="@+id/menu_titles" android:enabled="true" android:title="Titles" android:icon="@drawable/tab_titles" app:showAsAction="always" /> <item android:orderInCategory="2" android:id="@+id/menu_stream" android:enabled="true" android:title="Stream" android:icon="@drawable/tab_stream" app:showAsAction="always" /> <item android:orderInCategory="3" android:id="@+id/menu_showtimes" android:enabled="true" android:title="Showtimes" android:icon="@drawable/tab_showtimes" app:showAsAction="always" /> </menu>
注意
orderInCategory
,这是选项卡项从左到右的顺序。好的,现在我们已经将我们将要使用的视图放在一起。现在让我们进入 BottomNavigationView。
在 MainActivity 中获取 BottomNavigationView 并进行设置。
bottomNavigationView= FindViewById<BottomNavigationView>(Resource.Id.bottom_navigation);
此外,如果选项卡超过 3 个,BottomNavigationView 会隐藏标签。所以,让我们改变一下。将此辅助方法添加到您的代码中,并在像这样设置 BottomNavigationView 时调用它,
RemoveShiftMode(_navigationView);//Below the FindViewById private void RemoveShiftMode(BottomNavigationView view) // a Method in the Activity { var menuView = (BottomNavigationMenuView) view.GetChildAt(0); try { var shiftingMode = menuView.Class.GetDeclaredField("mShiftingMode"); shiftingMode.Accessible = true; shiftingMode.SetBoolean(menuView, false); shiftingMode.Accessible = false; for (int i = 0; i < menuView.ChildCount; i++) { var item = (BottomNavigationItemView)menuView.GetChildAt(i); item.SetShiftingMode(false); // set checked value, so view will be updated item.SetChecked(item.ItemData.IsChecked); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine((ex.InnerException??ex).Message); } }
现在,我们应该没事了。就是这样。我们完成了 BottomNavigationView 的设置。我们还没有为每个选项卡实现片段,所以点击选项卡不会显示任何内容。我们将在 ViewPager 中呈现片段。
现在,让我们设置 ViewPager。一、适配器,
public class ViewPagerAdapter : FragmentPagerAdapter { Fragment[] _fragments; public ViewPagerAdapter(FragmentManager fm, Fragment[] fragments) : base(fm) { _fragments = fragments; } public override int Count => _fragments.Length; public override Fragment GetItem(int position) => _fragments[position]; }
然后,ViewPager,
// find the view _viewPager = FindViewById<ViewPager>(Resource.Id.viewpager); // set the adapter _viewPager.Adapter = new ViewPagerAdapter(SupportFragmentManager, _fragments);
这就是设置 ViewPager 的原因。
当用户在 ViewPager 视图之间滑动时,ViewPager.PageSelected 事件被触发。同样,当用户点击 BottomNavigationView 中的选项卡(导航菜单项)时,将触发 BottomNavigationView.NavigationItemSelected 事件。我们必须 link 这两个事件才能使 BottomNavigationView 和 ViewPager 同步跳舞。以下是我们将如何做。
如下声明 BottomNavigationView 和 ViewPager 的事件处理程序,
// wireup the page selection event _viewPager.PageSelected += ViewPager_PageSelected; // wire up the selection event _navigationView.NavigationItemSelected += NavigationView_NavigationItemSelected;
当ViewPager页面被选中时,我们通知BottomNavigationView,反之亦然。像这样,
private void ViewPager_PageSelected(object sender, ViewPager.PageSelectedEventArgs e) { var item = _navigationView.Menu.GetItem(e.Position); _navigationView.SelectedItemId = item.ItemId; } void NavigationView_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e) { _viewPager.SetCurrentItem(e.Item.Order, true); }
就是这样。现在 BottomNavigationView 和 ViewPager 正在显示所选 fragment/page/tab 并通过平滑过渡相互更新。
最后一件事,为这些选项卡加载片段。
void InitializeTabs()
{
_fragments = new Fragment[] {
TheFragment.NewInstance("Genres", "tab_genres"),
TheFragment.NewInstance("Titles", "tab_titles"),
TheFragment.NewInstance("Stream", "tab_stream"),
TheFragment.NewInstance("Showtimes", "tab_showtimes")
};
}