具有多个顶级目的地的导航图

fin*_*usl 10 android navigation-drawer android-navigation android-jetpack

我在业余时间实现了一个Android应用程序(在Kotlin中,但这与问题无关),我尝试使用android jetpack和新库。我有一个带有导航抽屉的活动。我尝试遵循示例向日葵应用程序。它在主要活动中使用以下组合来启用导航抽屉背后的逻辑:

appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
setSupportActionBar(findViewById(R.id.toolbar))
setupActionBarWithNavController(navController, appBarConfiguration)
Run Code Online (Sandbox Code Playgroud)

关于此代码的注意事项:在导航抽屉中单击时,此代码将自动导航到正确的片段,然后关闭抽屉并保持选中状态,等等。所有这些样板代码。那很整洁,也可以。据我了解,导航抽屉菜单项的ID必须与导航图中的片段的ID匹配,并以此方式进行连接。

遇到的问题:当我使用导航抽屉转到导航图的起始片段以外的任何片段时,它将显示一个后退按钮,而不是汉堡包项目。那不是我所期望的,我希望它仍然是汉堡包,因为导航抽屉用于在相同级别的视图之间导航,而不是彼此嵌套,对吗?如果我通过单击片段中的元素(例如,列表->详细信息)导航到任何片段的子片段,则希望有一个后退按钮,但是如果我使用导航抽屉进行导航,则不会。

现在,我将问题追溯到生成AppBarConfiguration器,该生成器读取了带有导航图的构造函数The NavGraph whose start destination should be considered the only top level destination.,通过覆盖AppBarConfiguration以返回不同的顶级目的地(而不只是导航图的起始目的地),我可以很轻松地解决此问题。

但是我的问题是,为什么会有这种行为默认?是虫子吗?如果我不这样做,是否会违反Google的某些设计准则?导航抽屉中的每个元素是否都应该与我期望的处于同一水平?我是否想使用其他解决方案?

Eli*_* DC 20

您不必重写AppBarConfiguration。由于版本alpha7AppBarConfiguration具有用于所有顶级目标的一组ID的构造函数。

Set<Integer> topLevelDestinations = new HashSet<>();
topLevelDestinations.add(R.id.fragment1);
topLevelDestinations.add(R.id.fragment2);
appBarConfiguration = new AppBarConfiguration.Builder(topLevelDestinations)
                                             .setDrawerLayout(drawerLayout)
                                             .build();
NavigationUI.setupActionBarWithNavController(this, 
                                             this.navController,
                                             this.appBarConfiguration);
Run Code Online (Sandbox Code Playgroud)

这不是默认设置,因为导航图只有一个开始片段,应该始终是应用程序的单个入口点。

使用AppBarConfiguration编辑默认行为不会使其像以前一样工作,每个顶级片段都放在后堆栈上,因此后退按钮将转到所有顶级片段。目前尚不清楚如何将顶级片段作为后堆栈的第一个元素。


小智 10

我为这个问题做了一个简单的例子。 https://github.com/isaul32/android-sunflower

首先创建一组顶级目的地

val topLevelDestinations = setOf(R.id.garden_fragment,
        R.id.plant_list_fragment)
appBarConfiguration = AppBarConfiguration.Builder(topLevelDestinations)
        .setDrawerLayout(drawerLayout)
        .build()
Run Code Online (Sandbox Code Playgroud)

然后像这样覆盖 onSupportNavigateUp 函数

override fun onSupportNavigateUp(): Boolean {
    return NavigationUI.navigateUp(navController, appBarConfiguration)
}
Run Code Online (Sandbox Code Playgroud)

  • 仅当您使用默认的“ActionBar”时,才需要覆盖“onSupportNavigateUp()”的最后一步。如果您添加自己的“ToolBar”,则在调用“NavigationUI.setupWithNavController(Toolbar工具栏,NavController navController,AppBarConfiguration配置)”时已经实现了此行为。 (2认同)