我目前正在使用Android体系结构组件的cURL
,但是我的Navigation
遇到了问题。它在我的出发地时显示汉堡菜单,但其他Navigation Drawer
在显示向上箭头。我相信我的Fragments
设置不正确。
在这里您可以看到我的导航抽屉,其中显示2个项,即“主页”和“设置”。在这些片段中的任何一个片段中,您都应该看到“汉堡包”图标。
但是,当导航到“设置片段”时,它会显示“向上”箭头。
navigation_graph
我觉得<?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"
app:startDestination="@id/nav_home">
<!-- Start at HomeFragment -->
<fragment
android:id="@+id/nav_home"
android:name=".HomeFragment"
android:label="@string/home">
<!-- Navigate to the Search -->
<action
android:id="@+id/action_nav_home_to_nav_search"
app:destination="@id/nav_search" />
</fragment>
<fragment
android:id="@+id/nav_settings"
android:name=".SettingsFragment"
android:label="@string/settings">
<!-- Navigate to the Search -->
<action
android:id="@+id/action_nav_settings_to_nav_search"
app:destination="@id/nav_search" />
</fragment>
<fragment
android:id="@+id/nav_search"
android:name=".SearchFragment"
android:label="@string/search" />
</navigation>
和HomeFragment
应该以某种方式联系在一起,但我不确定如何定义。
SettingsFragment
然后在<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<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" />
</group>
</menu>
中,我像这样设置。我打电话给MainActivity
,但是我还必须亲自设置导航抽屉,并处理setupActionBarWithNavController
。
onNavigationItemSelected
build.gradle
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
}
谢谢。
答案 0 :(得分:5)
在较新的alpha(我有1.0.0-alpha07)中,他们增加了在调用topLevelDestinationIds
构造函数时定义AppBarConfiguration
的可能性。
所以我这样设置NavController
val navController = findNavController(R.id.nav_host_fragment)
val config = AppBarConfiguration(
setOf(
R.id.fistTopFragment,
R.id.secondTopFragment,
...
),
dr.drawerLayout
)
tb.setupWithNavController(navController, config)
dr
是MaterialDrawer,当然tb
是工具栏。
然后,它的行为就更像Gmail,至少对于ActionBarDrawerToggle
而言,后栈仍然保留。由于必须由我自己处理MaterialDrawer中的项目选择,因此,我将使用全局导航操作(包括popTo)减少向后堆栈的操作,以将其包含到导航图的根片段中,并暂时使用“欢迎屏幕”之类的内容。
另一种解决方法是自定义处理onBackPressed
。
您必须首先从活动布局中的主机片段中删除app:defaultNavHost="true"
。像这样
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()
}
}
对不起代码,我还在学习Kotlin,所以可能有更好的方法。
答案 1 :(得分:3)
恐怕它是feature of navigation component。
当您位于非根目录目标位置时,操作栏还将显示“向上”按钮,而在根目录目标位置时,抽屉图标也会显示抽屉图标,从而自动在它们之间进行动画处理。
如果需要,可以尝试使用setupWithNavController(NavigationView, NavController)并自己处理工具栏。
答案 2 :(得分:1)
出现在与BottomNavigationView
关联的选项卡片段上的向后箭头是预期的行为。但是,即使在著名的应用程序(Instagram,Youtube中带有底部标签)中,也没有看到它被“按原样”使用。例如,如果您导航到Youtube应用程序中的其他底部选项卡,然后单击设备后退选项,您会注意到它转到上一个选项卡片段,而不退出应用程序。因此,bottomnavigationview选项卡片段不是此处的根目标。
想提醒您前进时可能遇到的其他重要问题:
与BottomNavigationView
组合使用时,不允许重复使用片段
https://issuetracker.google.com/issues/110373186
如果您有多个活动,则向上按钮不会导航到上一个活动 https://issuetracker.google.com/issues/79993862
不过,您可以使用多个挂钩自定义行为:
onBackPressed
-如果打开则关闭抽屉布局
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
添加navController.addOnNavigatedListener(..)
并在侦听器内部自定义HomeAsUpIndicator图标
覆盖onOptionsItemSelected
以自定义ID为android.R.id.home
操作的菜单
设置自定义片段导航器以自定义片段的处理方式(替换或显示/隐藏)
navHostFragment = supportFragmentManager
.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return
val customNavigator = CustomFragmentNavigator(navHostFragment.requireContext(),
navHostFragment.childFragmentManager, navHostFragment.id)
navHostFragment.navController.navigatorProvider.addNavigator(customNavigator)
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.main_nav_graph)
navHostFragment.navController.graph = graph
请记住导航拱形组件仍处于alpha状态,因此请明智地使用它。
答案 3 :(得分:1)
如果需要,可以使用NavController.OnNavigatedListener并使用以下代码设置标题。
@Override
public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
mActivityBinding.toolbar.setTitle(destination.getLabel());
}
记住要在导航图中设置标签。
答案 4 :(得分:1)
我为这个问题做了一个简单的例子。解决方案与全能者的答案几乎相同。 https://github.com/isaul32/android-sunflower
首先创建一组顶级目的地
package main
import (
"fmt"
"math/rand"
"time"
)
type list []string
func main() {
s := list{
"Tanki",
"Left 4 Dead",
"Rocket League",
"Call Of Duty : AW",
}
s.shuffle()
s.print()
}
func (l list) print() {
for i, v := range l {
fmt.Println(i, v)
}
}
func (l list) shuffle() list {
src := rand.NewSource(time.Now().UnixNano())
r := rand.New(src)
for i := range l {
n := r.Intn(len(l) - 1)
l[i], l[n] = l[n], l[i]
}
return l
}
然后像这样覆盖onSupportNavigateUp函数
val topLevelDestinations = setOf(R.id.garden_fragment,
R.id.plant_list_fragment)
appBarConfiguration = AppBarConfiguration.Builder(topLevelDestinations)
.setDrawerLayout(drawerLayout)
.build()
答案 5 :(得分:0)
我认为您的菜单项应如下所示:
<?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>
希望这会有所帮助
编码愉快...
答案 6 :(得分:0)
我完全同意这里的观点,但这是图书馆的一部分
setupActionBarWithNavController
设置由AppCompatActivity.getSupportActionBar()返回的ActionBar以与NavController一起使用。
通过调用此方法,操作栏上的标题将在目的地更改时自动更新(假设有有效标签)。
导航图的起始目的地被认为是唯一的顶级目的地。如果给定的DrawerLayout不为null,则在导航图的开始目标上,ActionBar将显示抽屉图标。在所有其他目标上,ActionBar将显示“向上”按钮。调用navigationUp(NavController,DrawerLayout)处理“上移”按钮。
这对我来说是坏的,而不是预期的结果,所以我在做的仍然是在使用
的导航视图中使用它 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;
}
});
然后我为这些片段中的每个片段创建一个新的导航图,虽然不太好,但是我得到了预期的结果