Backpress 错误图标上的底部导航视图
Bottom Navigation View on Backpress wrong icon
我的 MainActivity 中有 3 个带有 NavigationGraph 和 BottomNavigationView 的片段。这些片段是 HomeFragment、DashboardFragment 和 NotificationFragment。 startDestination
是 DashboardFragment,所以当我启动应用程序时,它会显示 DashboardFragment。
当我按下后退按钮时出现问题。片段显示 DashboardFragment,但 BottomNavigationView 显示最右侧的菜单,即 NotificationFragment。我希望展示 DashboardFragment 和 DashboardMenu。如何解决?
这是我的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val view = ActivityMainBinding.inflate(layoutInflater)
setContentView(view.root)
val navController = findNavController(R.id.nav_host_fragment)
view.navView.setOnNavigationItemSelectedListener {
if (navController.currentDestination!!.id != it.itemId) {
val builder = NavOptions.Builder()
.setLaunchSingleTop(true)
if (it.order and Menu.CATEGORY_SECONDARY == 0) {
builder.setPopUpTo(findStartDestination(navController.graph).id, false)
}
val options = builder.build()
try {
navController.navigate(it.itemId, null, options)
} catch (e: IllegalArgumentException) {
e.printStackTrace()
}
}
true
}
navController.addOnDestinationChangedListener { _, destination, _ ->
val menu = view.navView.menu
for (i in 0 until menu.size()) {
val item = menu[i]
val menuId = item.itemId
val destinationId = destination.id
val checked = menuId == destinationId
item.isChecked = checked
}
}
}
尝试将此添加到 activity:
override fun onBackPressed() {
super.onBackPressed()
navView.setSelectedItemId(R.id.menu_dashbord)
//jump to dashbord fragment
}
我建议更改您的实现,以便它使用 androidx.navigation.ui 包中的 setupWithNavController 扩展函数。
在activity的xml
(...)
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/bottom_navigation_menu" />
(...)
在activity
a) 声明 bottomNavigation
private val bottomNavigation: BottomNavigationView by lazy { findViewById(R.id.bottom_navigation) }
b) 创建设置导航函数并在 onCreate 方法中调用它
private fun setupNavigation() {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
navController.addOnDestinationChangedListener(this)
bottomNavigation.setupWithNavController(navController)
}
这样后退按钮将自动正确处理
PS。如果您不希望在重新选择菜单项时重新创建片段,请在 bottomNavigationView 上设置 NavigationItemReselectedListener。
像 activity 的字段一样初始化 navController:
val navController by lazy { findNavController(R.id.nav_host_fragment) }
在 activity onCreate 中初始化底部导航:
bottom_nav?.setupWithNavController(navController)
在你的 activity 上重写这个乐趣(为了正确的后退按钮):
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp()
}
在菜单文件中添加相同的名称,在导航图中添加片段 ID。必须工作
另外,如果你想在你的片段中使用 navController 来导航某处:
protected lateinit var rootActivity: MainActivity
<...>
override fun onAttach(context: Context) {
super.onAttach(context)
rootActivity = activity as MainActivity
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
btn_action.setOnClickListener {
rootActivity.navController.navigate(R.id.action_id)
}
}
action_id
是你在导航图中写的动作的id
此外,从 onCreate()
中删除所有监听器
我的 MainActivity 中有 3 个带有 NavigationGraph 和 BottomNavigationView 的片段。这些片段是 HomeFragment、DashboardFragment 和 NotificationFragment。 startDestination
是 DashboardFragment,所以当我启动应用程序时,它会显示 DashboardFragment。
当我按下后退按钮时出现问题。片段显示 DashboardFragment,但 BottomNavigationView 显示最右侧的菜单,即 NotificationFragment。我希望展示 DashboardFragment 和 DashboardMenu。如何解决?
这是我的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val view = ActivityMainBinding.inflate(layoutInflater)
setContentView(view.root)
val navController = findNavController(R.id.nav_host_fragment)
view.navView.setOnNavigationItemSelectedListener {
if (navController.currentDestination!!.id != it.itemId) {
val builder = NavOptions.Builder()
.setLaunchSingleTop(true)
if (it.order and Menu.CATEGORY_SECONDARY == 0) {
builder.setPopUpTo(findStartDestination(navController.graph).id, false)
}
val options = builder.build()
try {
navController.navigate(it.itemId, null, options)
} catch (e: IllegalArgumentException) {
e.printStackTrace()
}
}
true
}
navController.addOnDestinationChangedListener { _, destination, _ ->
val menu = view.navView.menu
for (i in 0 until menu.size()) {
val item = menu[i]
val menuId = item.itemId
val destinationId = destination.id
val checked = menuId == destinationId
item.isChecked = checked
}
}
}
尝试将此添加到 activity:
override fun onBackPressed() {
super.onBackPressed()
navView.setSelectedItemId(R.id.menu_dashbord)
//jump to dashbord fragment
}
我建议更改您的实现,以便它使用 androidx.navigation.ui 包中的 setupWithNavController 扩展函数。
在activity的xml
(...)
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/bottom_navigation_menu" />
(...)
在activity
a) 声明 bottomNavigation
private val bottomNavigation: BottomNavigationView by lazy { findViewById(R.id.bottom_navigation) }
b) 创建设置导航函数并在 onCreate 方法中调用它
private fun setupNavigation() {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
navController.addOnDestinationChangedListener(this)
bottomNavigation.setupWithNavController(navController)
}
这样后退按钮将自动正确处理
PS。如果您不希望在重新选择菜单项时重新创建片段,请在 bottomNavigationView 上设置 NavigationItemReselectedListener。
像 activity 的字段一样初始化 navController:
val navController by lazy { findNavController(R.id.nav_host_fragment) }
在 activity onCreate 中初始化底部导航:
bottom_nav?.setupWithNavController(navController)
在你的 activity 上重写这个乐趣(为了正确的后退按钮):
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp()
}
在菜单文件中添加相同的名称,在导航图中添加片段 ID。必须工作
另外,如果你想在你的片段中使用 navController 来导航某处:
protected lateinit var rootActivity: MainActivity
<...>
override fun onAttach(context: Context) {
super.onAttach(context)
rootActivity = activity as MainActivity
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
btn_action.setOnClickListener {
rootActivity.navController.navigate(R.id.action_id)
}
}
action_id
是你在导航图中写的动作的id
此外,从 onCreate()
中删除所有监听器