如何使用导航体系结构组件将日志记录添加到导航备份或备份



我在Android应用程序中使用导航组件,它会自动为我提供备份和备份导航。现在我不想改变任何这些行为,但我想添加一些特定于用户按下工具栏中的向上按钮或后退按钮的片段的日志记录。

我试过了,但它只对后退按钮有效,我不知道如何保持默认的导航行为不变。此外,这似乎在活动级别添加了一个回调,所以它并不特定于我添加回调的片段。

看起来onOptionsItemSelected是为普通菜单项调用的,但不是为Up按钮调用的。

如何在不改变整个应用程序行为的情况下始终如一地处理此问题?

您非常接近答案
试试这个。

注意:此代码是从我的应用程序中复制的。根据您的要求进行更改。

活动中:

onCreate():中

// Observe action state live data
activityViewModel.actionStateMutableLiveData.observe(this, Observer { actionState ->
actionState?.let {
if (actionState != "NO_ACTION") {
when (actionState) {
"NAVIGATE_UP" -> {
if (!navController.navigateUp()) {
finish()
}
}
}
// Reset action state
activityViewModel.setActionState("NO_ACTION")
}
}
})

而且,

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
navController.currentDestination?.id?.let { currentDestinationId ->
return when (currentDestinationId) {
R.id.fragmentToLog -> {
false
}
else -> {
activityViewModel.setActionState("NAVIGATE_UP")
true
}
}
}
activityViewModel.setActionState("NAVIGATE_UP")
return true
}
else -> {
item.onNavDestinationSelected(findNavController(R.id.fragment_activitymain))
|| super.onOptionsItemSelected(item)
}
}
}

片段:

onViewCreated():中

requireActivity().onBackPressedDispatcher.addCallback(this) {
handleNavigateBack()
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
handleNavigateBack()
return true
}
}
return super.onOptionsItemSelected(item)
}
private fun handleNavigateBack() {
// TODO: Add your fragment logs here
activityViewModel.setActionState("NAVIGATE_UP")
}

活动视图模型:

// Action state
var actionStateMutableLiveData = MutableLiveData(NO_ACTION)
private set
fun setActionState(actionStateValue: String?) =
actionStateMutableLiveData.postValue(actionStateValue)

使用的概念:

  • MVVM体系结构
  • 实时数据&查看模型
  • Android架构导航组件

如果有任何不清楚的地方,请发表评论。

在您的活动中,您应该首先通过以下代码设置NavigationUI

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

在Fragment中,当用户在onOptionsItemSelected中单击工具栏,然后调用findNavController().navigateUp()时,您可以检测到

一个可能的解决方案包括三个步骤:定义一个接口,让所需的片段实现该接口,并在托管活动中覆盖onSupportNavigateUp/onNavigateUp/onBackPressed方法。

首先,定义一个接口,例如:

interface CustomNavAction {
fun logSomeStuff()
}

其次,将接口添加到所需的片段,例如:

class AFragment : Fragment(), CustomNavAction {
...
override fun logSomeStuff() {
Log.d("TAG", "Up or back")
}
...
}

最后,覆盖托管导航组件的"活动"中的onSupportNavigateUp/onNavigateUp/onBackPressed方法,找到当前片段并检查它是否实现了接口。如果是,你可以采取行动。例如:

override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
// find current fragment, and invoke custom action if up button is pressed
val navHostFragment = supportFragmentManager.fragments[0]
val currentFragment = navHostFragment.childFragmentManager.fragments[0]
if (currentFragment is CustomNavAction) {
(currentFragment as CustomNavAction).logSomeStuff()
}
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onBackPressed() {
super.onBackPressed()
... 
// similar logic as onSupportNavigateUp
}

通过这种方式,您不会干扰整体导航,并且只有实现接口的片段才会记录一些内容。

这个解决方案不是特定于片段的,但通过这种方式,您可以用更少的代码检测反向按压和导航

在Fragment中,onCreate添加此

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

// enable the callback, when we receive a back press event disable the callback and dispatch the event to the activity
requireActivity().onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Log.d(
"SomeTag",
"User pressed up back button to navigate back from fragment."
)
isEnabled = false
requireActivity().onBackPressed()
}
})
}

现在,在您的活动中,您需要覆盖默认的ToolBar#onNavigationOnClickListener()

toolbar.setNavigationOnClickListener {
val currentFragment = navHostFragment.childFragmentManager.primaryNavigationFragment
Log.d(
"SomeTag",
"User pressed up arrow to navigate back from fragment: $currentFragment"
)
navController.navigateUp(appBarConfiguration)
}

最新更新