如何使用导航组件处理片段内的向上按钮

Posted

技术标签:

【中文标题】如何使用导航组件处理片段内的向上按钮【英文标题】:How to handle up button inside fragment using Navigation Components 【发布时间】:2019-12-29 07:24:35 【问题描述】:

我正在制作一个简单的笔记应用程序,我有 2 个带有导航组件的片段,一个片段包含笔记列表,另一个用于编辑或创建新笔记。

MainActivity我加了

val navController = this.findNavController(R.id.host_fragment)
NavigationUI.setupActionBarWithNavController(this, navController)

然后覆盖onSupportNavigateUp()

override fun onSupportNavigateUp(): Boolean 
        val navController = this.findNavController(R.id.host_fragment)
        return navController.navigateUp()
    

NoteEditFragment

requireActivity().onBackPressedDispatcher.addCallback(this) 
        saveOrUpdateNote(noteId, note)
    

现在按下设备中的“后退按钮”时一切正常,但是当我按下屏幕左上角的“向上按钮”时,onBackPressedDispatcher.addCallback() 被触发。

我的问题是:如何处理我的NoteEditFragment 中的这个向上按钮?

提前致谢

【问题讨论】:

【参考方案1】:

终于找到了解决办法。

首先在 activity onCreate 方法中,我必须像以前一样连接导航:

val navController = this.findNavController(R.id.host_fragment)
NavigationUI.setupActionBarWithNavController(this, navController)

然后还是在MainActivity覆盖onSupportNavigateUp()

override fun onSupportNavigateUp(): Boolean

    val navController = this.findNavController(R.id.host_fragment)
    return navController.navigateUp()

然后在Fragment onCreateView 我不得不启用选项菜单:

setHasOptionsMenu(true)

然后在fragment 中我覆盖了onOptionsItemSelected

override fun onOptionsItemSelected(item: MenuItem): Boolean

    // handle the up button here
    return NavigationUI.onNavDestinationSelected(item!!,
        view!!.findNavController())
            || super.onOptionsItemSelected(item)

注意:我认为如果您有多个选项菜单,那么我认为您必须执行when (item) 语句来检查已选择的选项。

此外,如果您想处理设备后退按钮,那么您可以在 fragment onCreateViewMethod 中这样做:

requireActivity().onBackPressedDispatcher.addCallback(this)
    
        // handle back button

// change this line to whatever way you chose to navigate back          
findNavController().navigate(NoteEditFragmentDirections.actionNoteEditFragmentToNoteListFragment())
        

【讨论】:

非常感谢!我忘记了如何处理向上按钮! 超级干净流畅 对于那些正在寻找操作栏上后退按钮的 item.itemid 的人来说,它是:android.R.id.home。见:developer.android.com/reference/android/R.id#home【参考方案2】:

我认为接受的答案有点混乱。所以,我找到了一个干净的代码。它非常适合我的用例,因为按下设备后退按钮时我不需要做任何特别的事情。因此,这里有相同要求的任何人都可以按照我的代码进行操作。

在 MainActivity 的 onCreate 中:

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val navController = findNavController(R.id.nav_host_fragment)
    appBarConfiguration = AppBarConfiguration(navController.graph)
    // Check if androidx.navigation.ui.NavigationUI.setupActionBarWithNavController is imported
    // By default title in actionbar is used from the fragment label in navigation graph
    // To use the app name, remove label else if you want to add customized label specify it there
    setupActionBarWithNavController(this, navController, appBarConfiguration)

    ...

  

同样,在 MainActivity 本身中:

override fun onSupportNavigateUp(): Boolean 
    val navController = findNavController(R.id.fragment)
    // Check if androidx.Navigation.ui navigateUp is imported and used
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()

我添加了 cmets 以便更好地理解。如果您认为答案有帮助,请点赞。谢谢。快乐发展:)

编辑 1: 无需在片段中使用supportActionBar.setDisplayHomeAsUpEnabled(true)。 AppBarConfiguration 会处理它。

【讨论】:

【参考方案3】:

如果你使用 noActionBar 主题,并且你想使用自己的工具栏作为片段的 actionBar,你可以使用这个方法

在宿主活动中

override fun onSupportNavigateUp(): Boolean 
    return findNavController(R.id.navHostFragment).navigateUp()

在片段的onCreateView中

(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)
(activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)

【讨论】:

【参考方案4】:

您只需在 Activity 上设置 supportNavigateUp 即可。

MainActivity中:

private lateinit var navController: NavController

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    navController = navHostFragment.navController

    setupActionBarWithNavController(navController)


override fun onSupportNavigateUp(): Boolean 
    return navController.navigateUp() || super.onSupportNavigateUp()

在我的情况下它有效

【讨论】:

以上是关于如何使用导航组件处理片段内的向上按钮的主要内容,如果未能解决你的问题,请参考以下文章

底部应用栏在使用片段导航时向上/向下滑动(导航架构组件)

如何使向上按钮返回而不是打开导航抽屉

底部导航 如何从片段内部更改片段

使用导航架构操作点击返回按钮时如何避免片段重新创建?

Android导航组件ActionBar向上/父事件处理

在片段的工具栏中向上导航