NavigationView使用简介
Android支持直接创建带有NavigationView的Activity,这里主要介绍NavigationView的逻辑。
NavigationView通常是跟DrawerLayout一起使用。DrawerLayout下面就包含俩个控件,第一个是内容,第二个是滑屏。
页面
页面代码如下:
<?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".module.MainActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/Theme.frist.AppBarOverlay"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/bgbule" app:popupTheme="@style/Theme.frist.PopupOverlay" /> </com.google.android.material.appbar.AppBarLayout> <fragment android:id="@+id/nav_host_fragment_content_main" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:defaultNavHost="true" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/nav_hostfragment_main" /> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" app:srcCompat="@android:drawable/ic_dialog_email" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/nav_menu_main" /> </androidx.drawerlayout.widget.DrawerLayout>
容器1
如代码所示,内容里放了一个可以被控制的fragment,name为androidx.navigation.fragment.NavHostFragment代表他是被NavigationView控制的fragment。
app:navGraph属性,设置为nav_hostfragment_main,代表控制他的xml文件是navigation文件夹下的nav_hostfragment_main。
nav_hostfragment_main.xml文件如下:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_hostfragment_main" app:startDestination="@+id/nav_frist"> <fragment android:id="@+id/nav_frist" android:name="com.kiba.learn.module.Fragment.FristFragment" android:label="first" tools:layout="@layout/fragment_frist" /> </navigation>
app:layout_behavior属性为固定字符串【com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior】,代表他是在头部的bar之下。
容器2
容器2是NavigationView,app:headerLayout指定了NavigationView的Header的Xml文件;app:menu指定了NavigationView菜单的Xml文件。
菜单的xml很简单,就是一组item,如下:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_frist" android:icon="@drawable/ic_menu_gallery" android:title="frist" /> </group> </menu>
代码
Activity代码如下:
通过NavController指定页面内的fragment为可以被控制的fragment,然后实现,滑出的菜单点击,切换fragment。
private AppBarConfiguration mAppBarConfiguration; private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar);//设置自定义bar //region navView配置 mAppBarConfiguration = new AppBarConfiguration.Builder( R.id.nav_first) .setDrawerLayout(binding.drawerLayout) .build();//配置切换fragment时,使用的id NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);//指定页面内的fragment为可以被控制的fragment //绑定fragment和navigation的配置 NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(binding.navView, navController); binding.navView.setCheckedItem(R.id.nav_frist);//设置当前选中项 binding.navView.setNavigationItemSelectedListener(view->{ int s= view.getItemId(); return true; }); //endregion Fragment currentFragment = FragmentManager.findFragment(this.findViewById(R.id.nav_host_fragment_content_main));//获取当前Activity下的fragment } //显示并配置右上设置菜单 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.set_menu, menu); return true; } //显示并配置左上navigation控制按钮 @Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); return NavigationUI.navigateUp(navController, mAppBarConfiguration) || super.onSupportNavigateUp(); } //系统返回按钮触发 @Override public void onBackPressed() { fristFragment sf = (fristFragment)getFragment(fristFragment.class); Intent loginActivity=new Intent(this,LoginActivity.class); startActivity(loginActivity); super.onBackPressed(); } public Fragment getFragment(Class<?> clazz) { List<Fragment> fragments = getSupportFragmentManager().getFragments(); if (fragments!= null && fragments.size() > 0) { NavHostFragment navHostFragment = (NavHostFragment) fragments.get(0); List<Fragment> childfragments = navHostFragment.getChildFragmentManager().getFragments(); if(childfragments != null && childfragments.size() > 0){ for (int j = 0; j < childfragments.size(); j++) { Fragment fragment = childfragments.get(j); if(fragment.getClass().isAssignableFrom(clazz)){ return fragment; } } } } return null; }
PS1:使用FragmentManager可以获取到当前Activity下 的fragment 如:FragmentManager.findFragment(this.findViewById(R.id.xxx));
PS2:onCreateOptionsMenu的重新会让右上角的菜单显示,不重载则不显示。
PS3:onSupportNavigateUp会让左上角的菜单显示,不重载则不显示。
PS4:使用NavigationView导航fragment时,fragment的name是androidx.navigation.fragment.NavHostFragment,此时想获取指定的fragment可以使用getFragment函数,注意该函数在onCreate中获取不到fragment。
SFragment sf = (SFragment)getFragment(SurveyFragment.class);
----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!