android 使用导航组件自定义特定片段的“向上导航”行为

dxpyg8gm  于 2023-03-16  发布在  Android
关注(0)|答案(6)|浏览(149)

我想使用导航组件从片段添加自定义 * 向上导航 *
在我的build.gradle(app)中,我使用androidx.appcompat:appcompat:1.1.0-alpha04依赖项从活动访问onBackPressedDispatcher
因此,我在片段中实现了OnBackPressedCallback,并将回调注册到调度程序:

requireActivity().onBackPressedDispatcher.addCallback(this)

我希望按工具栏中的 navigate up 可以调用它,但它没有。按设备的后退按钮可以调用它。
是否有类似的方法在向上导航动作的片段中添加一些回调?

更新

按下工具栏中的 * 向上按钮 * 时,未调用覆盖方法onOptionsItemSelectedonSupportNavigateUp

vfh0ocws

vfh0ocws1#

我找到了解决办法
handleOnBackPressed()方法只在单击设备的后退按钮时调用。我想知道,为什么在按工具栏中的“向上按钮”时onOptionsItemSelected()onSupportNavigateUp()方法都没有被调用。答案是我使用了

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)

在Activity中设置带有导航组件工具栏,并使工具栏响应内部导航,按“向上按钮”不会调用Activity或片段中的任何重写方法。
而应使用

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的答案应该像一个魅力

5hcedyr0

5hcedyr02#

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

override fun onOptionsItemSelected(menuItem : MenuItem?) : Boolean {
    if (menuItem.getItemId() == android.R.id.home) {
        onBackPressedDispatcher.onBackPressed()
        return true // must return true to consume it here

    }
    return super.onOptionsItemSelected(menuItem)
}

分段覆盖时

override fun onAttach(context: Context) {
        super.onAttach(context)            

        //enable menu
        setHasOptionsMenu(true)

        requireActivity()
                .onBackPressedDispatcher
                .addCallback(this){
                   //true means that the callback is enabled
                    this.isEnabled = true
                    exitDialog() //dialog to conform exit
                }
    }

它的作用是:
触发对当前添加的OnBackPressedCallback回调的调用,调用顺序与添加时的顺序相反。仅当其OnBackPressedCallback#handleOnBackPressed()中的false最多时,才会调用任何以前添加的回调。
我在示例中使用的是AndroidX,因此导入将如下所示
import androidx.appcompat.app.AppCompatActivity .

o2rvlv0m

o2rvlv0m3#

此设置也有效,您无需在Activity中覆盖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,如果你有一个。

ozxc1zmp

ozxc1zmp4#

我已经在残篇中单独使用了这个方法:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val menuProvider = object : MenuProvider {
        override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
        }

        override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
            if (menuItem.itemId == android.R.id.home)
            ...
        }
     }

    lifecycle.addObserver(object : DefaultLifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {
            super.onResume(owner) 
            activity!!.addMenuProvider(menuProvider)
        }

        override fun onPause(owner: LifecycleOwner) {
            super.onPause(owner) 
            activity!!.removeMenuProvider(menuProvider)
        }
    })
}

还要求将其放在此处:https://issuetracker.google.com/issues/273299805

dwthyt8l

dwthyt8l5#

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

@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    
        }
    });
olhwl3o2

olhwl3o26#

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

1.创建[作业单元]:

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

2.关于支持向上导航[活动]:

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

3.自定义或禁用反按[片段]:

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

相关问题