如何使用导航组件处理片段内的向上按钮
How to handle up button inside fragment using Navigation Components
我正在制作一个简单的笔记应用程序,我有 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)
}
现在在设备中按下 "back button" 时一切正常,但是当我按下屏幕左上角的 "up button" 时会触发 onBackPressedDispatcher.addCallback()
。
我的问题是:如何处理 NoteEditFragment
中的这个向上按钮?
提前致谢
终于找到了解决方法。
首先在 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())
}
如果你使用 noActionBar 主题并且你想使用你自己的工具栏作为片段的 actionBar,你可以使用这个方法
在主机中activity
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.navHostFragment).navigateUp()
}
在fragment的onCreateView中
(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)
(activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
我认为接受的答案有点乱。所以,我找到了一个干净的代码。它非常适合我的用例,因为按下设备后退按钮时我不需要做任何特别的事情。所以这里有相同需求的朋友可以按照我的代码来做。
在 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()
}
我添加了评论以便更好地理解。如果您认为答案有帮助,请点赞。谢谢你。快乐发展:)
编辑 1:
无需在片段中使用 supportActionBar.setDisplayHomeAsUpEnabled(true)
。 AppBarConfiguration 会处理它。
以非常简单的方式,您只需要在 Activity 上设置 supportNavigateUp。
在主要Activity:
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()
}
在我的例子中它起作用了
我正在制作一个简单的笔记应用程序,我有 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)
}
现在在设备中按下 "back button" 时一切正常,但是当我按下屏幕左上角的 "up button" 时会触发 onBackPressedDispatcher.addCallback()
。
我的问题是:如何处理 NoteEditFragment
中的这个向上按钮?
提前致谢
终于找到了解决方法。
首先在 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())
}
如果你使用 noActionBar 主题并且你想使用你自己的工具栏作为片段的 actionBar,你可以使用这个方法
在主机中activity
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.navHostFragment).navigateUp()
}
在fragment的onCreateView中
(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)
(activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
我认为接受的答案有点乱。所以,我找到了一个干净的代码。它非常适合我的用例,因为按下设备后退按钮时我不需要做任何特别的事情。所以这里有相同需求的朋友可以按照我的代码来做。
在 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()
}
我添加了评论以便更好地理解。如果您认为答案有帮助,请点赞。谢谢你。快乐发展:)
编辑 1:
无需在片段中使用 supportActionBar.setDisplayHomeAsUpEnabled(true)
。 AppBarConfiguration 会处理它。
以非常简单的方式,您只需要在 Activity 上设置 supportNavigateUp。
在主要Activity:
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()
}
在我的例子中它起作用了