使用导航组件对某些片段进行自定义“向上导航”行为

Rok*_*ark 6 android android-fragments kotlin android-architecture-navigation

我想使用导航组件从片段添加自定义导航

在我中,build.gradle(app)我使用androidx.appcompat:appcompat:1.1.0-alpha04依赖项来访问onBackPressedDispatcher活动。

因此,我OnBackPressedCallback在片段中实现并注册了对调度程序的回调:

requireActivity().onBackPressedDispatcher.addCallback(this)
Run Code Online (Sandbox Code Playgroud)

我希望按工具栏中的向上导航会调用它,但事实并非如此。按设备的后退按钮可以正常调用它。

有没有类似的方法可以在向上导航操作中在片段中添加一些回调?

更新

覆盖的方法onOptionsItemSelectedonSupportNavigateUp并且在按下工具栏中的向上按钮时不会调用

Rok*_*ark 6

我找到了解决方案

handleOnBackPressed()方法仅在设备的后退按钮单击时调用。我想知道,为什么既不onOptionsItemSelected()也不onSupportNavigateUp()方法并没有被要求在工具栏按下“向上”按钮。答案是我用过

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
Run Code Online (Sandbox Code Playgroud)

在活动中使用导航组件来设置工具栏。这样一来,工具栏就可以响应内部导航的需要,按下“向上按钮”并没有在活动或片段中调用任何覆盖的方法。

而是应该使用

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
Run Code Online (Sandbox Code Playgroud)

这将使actionBar响应导航,因此我可以使用覆盖的功能onOptionsItemSelected()onSupportNavigateUp() 最佳位置(在我的情况下)在某些屏幕上的“向上按钮”单击上添加自定义行为。

onSupportNavigateUp()
Run Code Online (Sandbox Code Playgroud)

这样的托管活动

override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.mainNavHostFragment)
        return when(navController.currentDestination?.id) {
            R.id.destinationOfInterest -> {
                // custom behavior here 
                true
            }
            else -> navController.navigateUp()
        }
}
Run Code Online (Sandbox Code Playgroud)

但值得一说的是,如果您想直接在片段中实现自定义行为,@ Enzokie的答案应该像一个魅力

  • 是否必须在 Activity 中设置,还是可以在 Fragment 中设置? (6认同)

Jua*_*ler 6

此设置也有效,您无需onSupportNavigateUp在活动中覆盖:

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
toolbar.setNavigationOnClickListener {
    if (navController.currentDestination?.id == R.id.destinationOfInterest) {
        // Custom behavior here
    } else {
        NavigationUI.navigateUp(navController, configuration)
    }
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢设置 ,Toolbar因为它会自动处理向上导航并打开/关闭 ,DrawerLayout如果你有的话。

  • 这打开了一种方法“toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }” - 对我的情况非常有帮助,谢谢。 (2认同)

Enz*_*kie 5

You need to call onBackPressed() from onBackPressedDispatcher property. Assuming your Toolbar is properly setup you can use the code below in your Activity.

override fun onOptionsItemSelected(menuItem : MenuItem?) : Boolean {
    if (menuItem.getItemId() == android.R.id.home) {
        onBackPressedDispatcher.onBackPressed()
    }
    return super.onOptionsItemSelected(menuItem)
}
Run Code Online (Sandbox Code Playgroud)

What this does is :

以相反的顺序触发对当前添加的OnBackPressedCallback回调的调用。只有从其最 假的情况下OnBackPressedCallback#handleOnBackPressed() 才会调用以前添加的任何回调。

我在示例中使用的是AndroidX,因此导入看起来像

import androidx.appcompat.app.AppCompatActivity

  • 感谢您的回复,但当我按“向上按钮”时, onOptionsItemSelected 方法不会调用。但是当我在工具栏中选择另一个菜单项时就会出现这种情况。在片段和活动中都尝试过 (2认同)