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

时间:2019-04-29 13:31:11

标签: android android-fragments kotlin android-architecture-navigation

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

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

因此我在片段中实现了OnBackPressedCallback 注册到调度员的回调:

requireActivity().onBackPressedDispatcher.addCallback(this)

我希望在工具栏中按向上导航会调用它,但是不会。 按设备的后退按钮可以正常调用它。

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

更新

按下工具栏中的上按钮时,不会调用

覆盖的方法onOptionsItemSelectedonSupportNavigateUp

5 个答案:

答案 0 :(得分:2)

您需要从onBackPressed()属性调用onBackPressedDispatcher。假设您的工具栏设置正确,则可以在“活动”中使用以下代码。

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

这是什么:

  

触发对当前添加的OnBackPressedCallback的呼叫   以相反的顺序添加回调。只有最   来自其OnBackPressedCallback#handleOnBackPressed() false   之前添加的任何回调都会被调用。

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

import androidx.appcompat.app.AppCompatActivity

答案 1 :(得分:0)

以这种方式将点击事件添加到工具栏的后退按钮

@Override
public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
case android.R.id.home:
    // Toolbar back button pressed, do something you want    

default:
    return super.onOptionsItemSelected(item);
  }
}

另一种方式

  Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    // Title and subtitle
    toolbar.setNavigationOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // Toolbar back button pressed, do something you want    
        }
    });

答案 2 :(得分:0)

我找到了解决方法

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

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)

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

应该使用

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

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

onSupportNavigateUp()

托管活动之类的

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()
        }
}

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

答案 3 :(得分:0)

此设置也可以使用,您无需在活动中覆盖onSupportNavigateUp

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

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

答案 4 :(得分:0)

我使用以下步骤自定义了(直接在 Fragment 中) 工具栏上的背景:

1. onCreate [活动]:

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

2. onSupportNavigateUp [活动]:

override fun onSupportNavigateUp(): Boolean {
        onBackPressedDispatcher.onBackPressed()
        return super.onSupportNavigateUp()
    }

3.自定义或禁用 backpress [Fragment]:

requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
           isEnabled = false
           // enable or disable the backpress
       }