Xamarin Android底部导航未在所有屏幕上显示

时间:2019-01-29 08:03:12

标签: android xamarin xamarin.android bottomnavigationview

我已经在Xamarin Android中实现了底部导航。单击底部导航栏中的每个图标时,我需要显示不同的屏幕。 我在主要活动中工作正常,但是在底部导航项的“选择”上,如何显示新屏幕并保持底部导航可见。 单击底部导航栏中的图标时,我再次设置Content,以便隐藏底部导航栏(因为加载了没有底部导航栏的新内容)。

我在Xamarin Android上的经验很少,所以不知道是否有布局页面之类的东西可以容纳底部导航。

enter image description here

enter image description here

我了解了框架布局和片段,但不知道如何使用底部导航来实现。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

底部栏添加到第一个活动中。如果您更改活动,则选择后底部的栏将消失。

您需要在视图分页器中添加片段才能实现

您可以查看此tutorial

您还可以看到此代码sample

答案 1 :(得分:1)

由于您正在更改Activity的ContentView,因此它消失了:

您可以按照以下步骤获得BottomNavigationView:

  • 由于我们正在处理Fragments,因此我将MainActivity基类更改为Android.Support.V7.App.AppCompatActivity,是的,我们将使用Android支持库V4。由于我正在处理Fragments,因此我将更改MainActivity 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事件。我们必须链接这两个事件以使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会显示选定的片段/页面/选项卡,并通过平滑过渡相互更新。

最后一件事,为这些选项卡加载片段。

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