主要记录参考google NavigationAdvancedSample示例对项目进行多返回栈改造时需注意的事项。快捷可直接看注意事项的第一句。
0. 需求描述
需要让底部导航的每个菜单项的控制的页面拥有自己独立的任务栈,以便于底部导航切换时,仍然保留在已经导航到的位置。
比如底部导航菜单是A, B, C 子页面,底部导航在A页面,A页面点击进如到A1,然后通过底部导航切换到B后再切换回A,A菜单页面仍然停留再A1而不是退回到A的home页。
可以进一步参看google官方示例集 architecture-components-samples 里面找到NavigationAdvancedSample示例项目,该项目基本演示了如何使用Navigation组件支持返回栈的情况。我在使用过程中,主要也是参考这一案例进行改造。
1. 示例拉取
我在拉取示例并运行示例时,由于国内网络原因编译还是有点问题,将一些依赖的仓库改成阿里云的镜像解决问题。注释掉的部分被替换
-
versions.gradle 文件里面镜像替换如下
def addRepos(RepositoryHandler handler) { handler.maven { url 'https://maven.aliyun.com/repository/google' } handler.maven { url 'https://maven.aliyun.com/repository/jcenter' } // handler.google() // handler.jcenter() handler.maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } }
-
项目级build.gradle文件镜像替换如下
repositories { maven { url 'https://maven.aliyun.com/repository/google' } // google() }
替换后在国内环境下运行就流畅了
2. 官方示例分析
该示例主要演示了Navigation组件+BottomNavigationView底部导航控件的使用。
项目运行起来后我们可以看到底部导航菜单项是Home, Leaderboard, Register。点击相应的菜单项目,分别会进入到相应任务栈的主页面。在home页,点击进入到About页面,通过底部导航切换到Leaderboard或者Register后再切回来,Home菜单页依然保持在About页面。同样其他两个菜单页面也是这样。这就是我们需要达到的效果。
3. 注意事项
-
底部导航菜单子项的id要与导航文件根id保持一致
个人建议最好是底部导航菜单item的id,该id所对应的导航文件名,该导航文件的根id,这三者保持一致。这样更规范、更不容易出错一些。
-
宿主页面使用的是androidx.fragment.app.FragmentContainerView
以往的宿主页面多使用的是如下
<fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/nav_view" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:navGraph="@navigation/nav_graph_main" />
但是该示例中使用的宿主页面是
<androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/nav_view" />
暂时还没研究过区别或者继续使用以前的行不行