使用 bottomsheet 的操作打开另一个 dialogfragment 而不会崩溃 android 导航组件
Use bottomsheet's action to open another dialogfragment without crashing android navigation component
-
android
-
android-dialogfragment
-
bottom-sheet
-
android-architecture-components
-
android-architecture-navigation
我有 Fragment A、BottomSheetDialogFragment B 和 DialogFragment C。我希望能够从 B 选择一个动作,关闭 B 返回 A,然后使用导航实时数据从 A 导航到 C。
A 和 B 共享相同的 activityViewModel。我的意图是,当单击 B 中的操作按钮时,它将关闭 B,修改 activityViewModel 中的标志,A 将观察标志的变化并随后打开 C。但是,我收到一个错误,我认为它认为我正在从 B 导航到 C(而不是 A 到 C):
java.lang.IllegalArgumentException: 导航目的地...action_FragmentA_to_DialogFragmentC 对此 NavController
未知
我认为异常是由于程序认为操作是从 B 到 C。
class DetailBottomSheet : BottomSheetDialogFragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private val detailViewModel by activityViewModels<DetailViewModel>() { viewModelFactory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding.bottomSheetAction.setOnClickListener {
dismiss()
detailViewModel.setBottomSheetDialogType(1)
}
}
}
class DetailFragment : Fragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private val detailViewModel by activityViewModels<DetailViewModel>() { viewModelFactory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
detailViewModel.bottomSheetDialogType.observe(viewLifecycleOwner, Observer {
when (it) {
1 -> detailViewModel.navigateToDialogFragmentC(args.id)
else -> {}
}
})
detailViewModel.navigateToDialogFragmentC.observe(
viewLifecycleOwner,
WrapperEventObserver {
Thread.sleep(500) // thought this would allow wait time for bottomsheet to dismiss, but doesn't make a difference
val action =
DetailFragmentDirections.actionFragmentAToDialogFragmentC(it)
findNavController().navigate(action)
})
}
}
在这种情况下,我可以使用哪些修复程序来正确导航?
在任何 DialogFragment
上调用 dismiss()
异步更新 NavController
状态 - 这意味着从 NavController
的角度来看,您 是 当你的 bottomSheetDialogType
侦测器开火时仍然在 DetailBottomSheet
。
您应该改用 findNavController().popBackStack()
,它将同步更新 NavController
的状态(有效地将您移回 A)并调用 dismiss()
本身来隐藏底部 sheet对话框。
binding.bottomSheetAction.setOnClickListener {
findNavController().popBackStack()
detailViewModel.setBottomSheetDialogType(1)
}
android
android-dialogfragment
bottom-sheet
android-architecture-components
android-architecture-navigation
我有 Fragment A、BottomSheetDialogFragment B 和 DialogFragment C。我希望能够从 B 选择一个动作,关闭 B 返回 A,然后使用导航实时数据从 A 导航到 C。
A 和 B 共享相同的 activityViewModel。我的意图是,当单击 B 中的操作按钮时,它将关闭 B,修改 activityViewModel 中的标志,A 将观察标志的变化并随后打开 C。但是,我收到一个错误,我认为它认为我正在从 B 导航到 C(而不是 A 到 C):
java.lang.IllegalArgumentException: 导航目的地...action_FragmentA_to_DialogFragmentC 对此 NavController
未知我认为异常是由于程序认为操作是从 B 到 C。
class DetailBottomSheet : BottomSheetDialogFragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private val detailViewModel by activityViewModels<DetailViewModel>() { viewModelFactory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding.bottomSheetAction.setOnClickListener {
dismiss()
detailViewModel.setBottomSheetDialogType(1)
}
}
}
class DetailFragment : Fragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private val detailViewModel by activityViewModels<DetailViewModel>() { viewModelFactory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
detailViewModel.bottomSheetDialogType.observe(viewLifecycleOwner, Observer {
when (it) {
1 -> detailViewModel.navigateToDialogFragmentC(args.id)
else -> {}
}
})
detailViewModel.navigateToDialogFragmentC.observe(
viewLifecycleOwner,
WrapperEventObserver {
Thread.sleep(500) // thought this would allow wait time for bottomsheet to dismiss, but doesn't make a difference
val action =
DetailFragmentDirections.actionFragmentAToDialogFragmentC(it)
findNavController().navigate(action)
})
}
}
在这种情况下,我可以使用哪些修复程序来正确导航?
在任何 DialogFragment
上调用 dismiss()
异步更新 NavController
状态 - 这意味着从 NavController
的角度来看,您 是 当你的 bottomSheetDialogType
侦测器开火时仍然在 DetailBottomSheet
。
您应该改用 findNavController().popBackStack()
,它将同步更新 NavController
的状态(有效地将您移回 A)并调用 dismiss()
本身来隐藏底部 sheet对话框。
binding.bottomSheetAction.setOnClickListener {
findNavController().popBackStack()
detailViewModel.setBottomSheetDialogType(1)
}