Android导航架构组件-导航抽屉图标
我目前正在使用Android架构组件的Android导航架构组件-导航抽屉图标,android,navigation-drawer,android-jetpack,android-architecture-navigation,android-components,Android,Navigation Drawer,Android Jetpack,Android Architecture Navigation,Android Components,我目前正在使用Android架构组件的导航,但我的导航抽屉遇到了问题。当我到达目的地时,它会显示汉堡包菜单,但其他片段会显示向上箭头。我想我的导航图设置不正确 在这里你可以看到我的导航抽屉,显示了两个项目,主页和设置。在这些片段中,您应该看到汉堡图标 但是,当导航到设置片段时,它会显示向上箭头 navigation.graph.xml 主要活动 然后在MainActivity中,我只是这样设置它。我用NavController调用了setupActionBar,但我还必须自己实际设置导航抽屉
导航
,但我的导航抽屉遇到了问题。当我到达目的地时,它会显示汉堡包菜单,但其他片段会显示向上箭头。我想我的导航图设置不正确
在这里你可以看到我的导航抽屉,显示了两个项目,主页和设置。在这些片段中,您应该看到汉堡图标
但是,当导航到设置片段时,它会显示向上箭头
navigation.graph.xml
主要活动
然后在MainActivity
中,我只是这样设置它。我用NavController调用了setupActionBar
,但我还必须自己实际设置导航抽屉,并处理所选导航项的onNavigationItem
private fun setupNavigation() {
navController = findNavController(R.id.mainNavigationFragment)
setupActionBarWithNavController(this, navController, drawer_layout)
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
nav_view.setNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val current = navController.currentDestination.id
if (item.itemId != current) {
navController.navigate(item.itemId)
}
drawer_layout.closeDrawers()
return true
}
格雷德尔先生
// Navigation
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha04'
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha04'
谢谢。恐怕这是一个错误
当您在非根目标上时,操作栏还将显示“向上”按钮,当您在根目标上时,操作栏将显示抽屉图标,并在它们之间自动设置动画
如果需要,您可以尝试自己使用和处理工具栏。与BottomNavigationView
关联的选项卡片段上出现的后退箭头是一种预期行为。然而,即使在著名的应用程序(Instagram、Youtube等有底部标签的应用程序)中,也没有看到它被“按原样”使用。例如,若你们在Youtube应用程序中导航到不同的底部选项卡,然后单击设备返回选项,你们会注意到它会转到上一个选项卡片段,而不是退出应用程序。因此,bottomnavigationview选项卡片段在这里不是根目的地
希望在前进过程中注意到可能遇到的其他重要问题:
- 它不允许将片段与
BottomNavigationView
- 如果有多个活动,“向上”按钮不会向上导航到上一个活动
但是,有几个钩子可用于定制行为:
on反按
-如果抽屉打开,则关闭抽屉布局
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
添加navController.addOnNavigatedListener(..)
并在listener内自定义HomeAsUpIndicator图标
覆盖OnOptions ItemSelected以使用idandroid.R.id.home
操作自定义菜单
设置自定义片段导航器以自定义片段的处理方式(替换或显示/隐藏)
请记住,导航拱门组件仍在alpha中,因此请明智地使用它。我认为您的菜单项应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/nav_home"
android:icon="@drawable/ic_home_white_24dp"
android:title="@string/home" />
<item
android:id="@id/nav_settings"
android:icon="@drawable/ic_settings_white_24dp"
android:title="@string/settings" />
</menu>
希望这有帮助
快乐编码 如果需要,可以使用和使用下面的代码来设置标题
@Override
public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
mActivityBinding.toolbar.setTitle(destination.getLabel());
}
记住在导航图中设置标签。我完全同意这里的观点,但它是库的一部分
setupActionBarWithNavController
设置AppCompatActivity.getSupportActionBar()返回的ActionBar,以便与NavController一起使用
通过调用此方法,当目标更改时(假设存在有效标签),操作栏中的标题将自动更新
导航图的起始目的地被视为唯一的顶级目的地。如果给定的抽屉布局非空,则在导航图的开始目标上,ActionBar将显示抽屉图标。在所有其他目的地,ActionBar将显示向上按钮。调用navigateUp(导航控制器,抽屉布局)处理向上按钮。
这对我来说是坏的,不是期望的结果,所以我所做的仍然是使用导航视图使用它
navController = Navigation.findNavController(this, R.id.nav_host);
NavigationUI.setupWithNavController(navigationView,navController);
然后有一个监听器来更新标题和其他我想更改的内容
navController.addOnNavigatedListener((controller, destination) -> {
setToolbarColour(R.color.primary);
switch (destination.getId()){
case R.id.dashBoard :
setToolbarColour(android.R.color.transparent);
break;
case R.id.requests :
toolbar.setTitle(getString(R.string.request));
break;
}
});
val navController = findNavController(R.id.nav_host_fragment)
val config = AppBarConfiguration(
setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
),
dr.drawerLayout
)
tb.setupWithNavController(navController, config)
override fun onBackPressed() {
val navController = findNavController(R.id.nav_host_fragment)
if (navController.currentDestination == null
|| navController.currentDestination!!.id in setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
)
) {
super.onBackPressed()
} else {
navController.navigateUp()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, appBarConfiguration)
}
然后,我为这些片段中的每一个创建了一个新的导航图,虽然不是很好,但我在较新的alphas(我有1.0.0-alpha07)中得到了预期的结果,他们在调用AppBarConfiguration
构造函数时增加了定义TopLevelDestinationId
的可能性
所以我把导航控制器设置成这样
navController.addOnNavigatedListener((controller, destination) -> {
setToolbarColour(R.color.primary);
switch (destination.getId()){
case R.id.dashBoard :
setToolbarColour(android.R.color.transparent);
break;
case R.id.requests :
toolbar.setTitle(getString(R.string.request));
break;
}
});
val navController = findNavController(R.id.nav_host_fragment)
val config = AppBarConfiguration(
setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
),
dr.drawerLayout
)
tb.setupWithNavController(navController, config)
override fun onBackPressed() {
val navController = findNavController(R.id.nav_host_fragment)
if (navController.currentDestination == null
|| navController.currentDestination!!.id in setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
)
) {
super.onBackPressed()
} else {
navController.navigateUp()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, appBarConfiguration)
}
其中dr
是MaterialDrawer,当然是tb
工具栏
然后它的行为更像Gmail,至少对于ActionBarDrawerToggle
,后堆栈仍然保留。因为我必须自己处理MaterialDrawer中的项目选择,所以我将使用全局导航操作和包含的popTo将后堆栈操作减少到导航图的根片段,并暂时使用类似“欢迎屏幕”的东西
另一种解决方法是自定义处理onBackPressed
。
您必须首先从活动布局中的主机片段中删除app:defaultNavHost=“true”
。像这样的
navController.addOnNavigatedListener((controller, destination) -> {
setToolbarColour(R.color.primary);
switch (destination.getId()){
case R.id.dashBoard :
setToolbarColour(android.R.color.transparent);
break;
case R.id.requests :
toolbar.setTitle(getString(R.string.request));
break;
}
});
val navController = findNavController(R.id.nav_host_fragment)
val config = AppBarConfiguration(
setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
),
dr.drawerLayout
)
tb.setupWithNavController(navController, config)
override fun onBackPressed() {
val navController = findNavController(R.id.nav_host_fragment)
if (navController.currentDestination == null
|| navController.currentDestination!!.id in setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
)
) {
super.onBackPressed()
} else {
navController.navigateUp()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, appBarConfiguration)
}
很抱歉,我还在学习Kotlin,所以可能有更好的方法来实现这一点。我为这个问题举了一个简单的例子。解决方案几乎和全能者的答案相同
首先创建一组顶级目的地
val topLevelDestinations = setOf(R.id.garden_fragment,
R.id.plant_list_fragment)
appBarConfiguration = AppBarConfiguration.Builder(topLevelDestinations)
.setDrawerLayout(drawerLayout)
.build()
然后像这样重写onSupportNavigateUp函数
navController.addOnNavigatedListener((controller, destination) -> {
setToolbarColour(R.color.primary);
switch (destination.getId()){
case R.id.dashBoard :
setToolbarColour(android.R.color.transparent);
break;
case R.id.requests :
toolbar.setTitle(getString(R.string.request));
break;
}
});
val navController = findNavController(R.id.nav_host_fragment)
val config = AppBarConfiguration(
setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
),
dr.drawerLayout
)
tb.setupWithNavController(navController, config)
override fun onBackPressed() {
val navController = findNavController(R.id.nav_host_fragment)
if (navController.currentDestination == null
|| navController.currentDestination!!.id in setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
)
) {
super.onBackPressed()
} else {
navController.navigateUp()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, appBarConfiguration)
}
我试着按照指导原则,在“根目的地”上显示一个汉堡包图标,在“非根目的地”上显示向上按钮,但在“主目的地”以外的其他“根目的地”上显示向上按钮。根据创建者的说法,这是有意为之的行为,所以你只是在与库作斗争。至于我,我其实喜欢有一个启动屏幕,即使是抽屉。当我转到“设置”时,很有可能,当我按“上一步”时,我想继续使用该应用程序,而不是最终进入launcher。事实上,其中一条评论说这实际上是一个bug。它正在被追踪。您所指的问题涉及嵌套图。你的情况似乎不是这样。但是无论如何,试一下新版本。我意识到我实际上正在运行alpha04