首先说一下这个的实现效果类似我们现在实现的方式ViewPager切换fragment,我们可以更简单,更优雅的实现我们的目标,毕竟Google推出的框架嘛,感觉还是不错的,个人感觉还是得看一下官方文档,虽然是英文,不过一点点翻译呗,每一步都讲得蛮细的。
首先配置一下gradle:
implementation 'android.arch.navigation:navigation-fragment:1.0.0' implementation 'android.arch.navigation:navigation-ui:1.0.0' implementation 'com.android.support:design:28.0.0' implementation 'com.android.support:appcompat-v7:28.0.0' implementation "com.android.support:support-v4:28.0.0"
接下来我们就可以使用相关的api啦!
首先我们新建一个activity,叫MainActivity,布局文件如下:
<fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/navigation" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/navigation" android:layout_width="match_parent" android:layout_height="56dp" android:layout_alignParentBottom="true" app:menu="@menu/my_navigation_items" />
首先我们看到我们切换的页卡view是BottomNavigationView ,上面换成了fragment角标,这里的id可以随意给,name我们必须声明成androidx.navigation.fragment.NavHostFragment ,不然找不到映射的fragment。
这里的defaultNavHost属性为true,要求我们在跳转到下一个fragment之后,返回键的相应是回到上一个fragment这个和webView的histtory是一样的。
重点是navGraph这个属性,我们定义这个navigation文件:
如上图所示,新建这个navigation文件夹的过程也很简单:
然后输入名字,确定即可。
这样我们就可以在布局里面做一些我们自己要做的事情了,我的文件如下:
大家看到了里面包含了三个fragment,我们再看一下布局文件:
<?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_graph" app:startDestination="@id/blankFragment"> <fragment android:id="@+id/blankFragment" android:name="com.example.jespactdemo.BlankFragment" android:label="fragment_blank" tools:layout="@layout/fragment_blank" /> <fragment android:id="@+id/secondFragment" android:name="com.example.jespactdemo.SecondFragment" android:label="secondfragment" tools:layout="@layout/secondfragment" /> <fragment android:id="@+id/mineFragment" android:name="com.example.jespactdemo.MineFragment" android:label="fragment_mine" tools:layout="@layout/fragment_mine" /> </navigation>
除了最外层的角标不一样之外,其余的跟我们平时写的xml很类似,我们声明了fragment,指明了预览layout,这里的id我们先记着很重要,后面我再说。
我们发现在navigation里面有一个属性startDestination,我们指明了blankFragment,再看看design的时候,blankFragment预览图左上角有一个小房子的图案:
这说明我们activity第一次进来的时候关联显示的fragment就是它了。
接下来我们再看看底部切换布局怎么实现,首先我们创建一个menu文件夹,然后在创建一个menu的xml,里面的内容如下:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/blankFragment" android:title="消息" android:icon="@mipmap/ic_launcher" /> <item android:id="@+id/secondFragment" android:title="首页" android:icon="@mipmap/ic_launcher" /> <item android:id="@+id/mineFragment" android:title="我的" android:icon="@mipmap/ic_launcher" /> </menu>
这里很简单,大家都能看得懂,这里我们注意一下这里的id,之前我说过创建fragment的时候声明的id也很重要,这两者的有什么关系呢?关系就是我们一定要一一对应,完全一样才可以形成映射关系。
最后我们看一下MainActivity的实现:
mBottomNav = findViewById(R.id.navigation); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); NavigationUI.setupWithNavController(mBottomNav, navController);
@Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); return NavigationUI.navigateUp(navController, appBarConfiguration) || super.onSupportNavigateUp(); } @Override public boolean onOptionsItemSelected(MenuItem item) { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item); }
主要就是这两行代码即可,还要重写这两个方法来实现点击就可以切换了,首先我们要获取到NavController 对象,这个对象获取有三种方式,这是其中一种了,然后调用NavigationUI这个类setup底部页卡和NavController 就关联起来了,这样就实现了切换功能,很重要的一点就是menu 的选项id一定要和nav的fragment的id保持一致,至此就完结了,我们发现我们省了很多切换逻辑代码,还有很多xml布局,这让我们承载fragment的activity更加轻松简洁,大大缩短了逻辑代码,还有一个提示:页卡切换fragment我们也可以在nav布局设置哦D)