我正在使用Android的导航架构组件。
对于我的一个片段,我希望拦截“后退”和“向上”导航,以便在放弃用户未保存的任何更改之前显示一个确认对话框。(编辑事件详细信息后按back/up时的行为与默认日历应用程序相同)
我目前的方法(未经测试)如下:
对于“向上”导航,我覆盖片段上的选项ItemSelected:
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if(item?.itemId == android.R.id.home) {
if(unsavedChangesExist()) {
// TODO: show confirmation dialog
return true
}
}
return super.onOptionsItemSelected(item)
}
为了“返回”导航,我在片段及其活动之间创建了一个自定义接口和回调系统:
interface BackHandler {
fun onBackPressed(): Boolean
}
class MainActivity : AppCompatActivity() {
...
val backHandlers: MutableSet<BackHandler> = mutableSetOf()
override fun onBackPressed() {
for(handler in backHandlers) {
if(handler.onBackPressed()) {
return
}
}
super.onBackPressed()
}
...
}
class MyFragment: Fragment(), BackHandler {
...
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is MainActivity) {
context.backHandlers.add(this)
}
}
override fun onDetach() {
(activity as? MainActivity)?.backHandlers?.remove(this)
super.onDetach()
}
override fun onBackPressed(): Boolean {
if(unsavedChangedExist()) {
// TODO: show confirmation dialog
return true
}
}
...
}
对于这样一件简单的事情来说,这一切都是相当粗糙和陈词滥调的。有更好的方法吗?
对于向上导航,只需覆盖OnOptions ItemSelected()
override fun onOptionsItemSelected(item: MenuItem): Boolean =
when (item.itemId) {
android.R.id.home -> {
showDialog() // show your dialog here
true
}
else -> super.onOptionsItemSelected(item)
}
使用导航架构组件,您可以执行以下操作:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressedDispatcher.onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(this) {
if (*condition for showing dialog here*) {
// Show dialog
} else {
// pop fragment by calling function below. Analogous to when the user presses the system UP button when the associated navigation host has focus.
findNavController().navigateUp()
}
}
}
截至androidx。appcompat:appcompat:1.1.0-beta01,为了拦截带有导航组件的后退按钮,您需要在BackpressedDispatcher上添加一个回调。此回调必须扩展OnBackPressedCallback,并覆盖handleOnBackPressedOnBackPressedDispatcher遵循责任链模式来处理回调。换句话说,如果您将回调设置为enabled,则只会执行回调。否则,
OnBackPressedDispatcher将忽略它并继续下一个回调,依此类推,直到它找到一个已启用的回调(例如,当您有多个回调时,这可能很有用)。更多信息请点击此处。
因此,为了显示您的对话框,您必须执行类似的操作:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val callback = object : OnBackPressedCallback(true /** true means that the callback is enabled */) {
override fun handleOnBackPressed() {
// Show your dialog and handle navigation
}
}
// note that you could enable/disable the callback here as well by setting callback.isEnabled = true/false
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
}
至于向上按钮,似乎(至少目前)没有太多的可能性。到目前为止,我能找到的使用导航组件的唯一选择是为导航本身添加一个侦听器,它将同时处理两个按钮:
navController.addOnDestinationChangedListener { navController, destination ->
if (destination.id == R.id.destination) {
// do your thing
}
}
无论如何,这有一个警告,即允许添加侦听器的活动或片段知道可能不应该知道的目的地。
我正在我的应用程序中尝试导航架构组件。早些时候,我使用片段事务来实现以下功能。基本上,我想从导航。 碎片- 如果我正在使用导航组件并尝试 然后结果是FragmentA被FragmentB替换并且背景片段不可见。 我想知道一个解决方案,如果导航架构组件允许的话。 附言:我听说过嵌套导航主机,但从内部使用它好吗。 更新: FragmentB将有进一步交易的行动,例如: 碎片- 当用户按下后退按钮时,片
我正试图在现有的应用程序中实现新的Android导航组件。我有两个片段除了名字外都是一样的。当我将startDestination设置为fragment2时,片段似乎显示正确。当startDestination设置为fragment1时,我看不到膨胀的视图,但我确实看到了“Fragment 1 created”toast。 我做错了什么? 导航图。xml 主活动布局: Fragment1布局: 依
是否可以将新的导航架构组件与DialogFragment一起使用?我必须创建自定义导航器吗? 我很乐意将它们与导航图中的新功能结合使用。
数据税务文件规定 当表模式存在时,Cassandra只能从快照恢复数据。如果您尚未备份该模式,[...] 架构的完整备份需要什么?简单地备份< code >系统密钥空间?
我们为您原片导出功能,只有开通原片备份功能,才可以使用导出功能。 点击导出,可导出该视频原片到本地,尚在处理状态视频,需等处理结束后方可导出。
我正在使用BottomSheetDialogFraenge显示几个自定义设置的。 要求: 当我点击任何选项卡在BottomSheetDialogFraance我替换的片段,并将其添加到backstack,以便当用户点击的onBackPress或向上的行动,它应该回到最后设置的BottomSheetDialogFraank的片段。 我想使用导航架构组件来简化我的事务。 问题:如果我使用导航架构组件从