OnBackPressedCallback 内的 NavController 出现问题
Trouble with NavController inside OnBackPressedCallback
我在 OnBackPressedCallback 中收到 does not have a NavController set
错误。这是代码
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
fragmentView = inflater.inflate(R.layout.patient_info_fragment, container, false)
if(Utils.connectedToInternet()){
fragmentView.pastScreeningsButton.visibility = View.GONE
}
requireActivity().onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Navigation.findNavController(fragmentView).navigate(R.id.action_patientInfoFragment_to_patientsList)
}
})
setHasOptionsMenu(true)
return fragmentView
}
当我回到实现它的片段时,我才收到这个错误。
我在主页片段中有 android:name="androidx.navigation.fragment.NavHostFragment"
。
澄清一下,我正在使用导航控制器围绕我的应用程序进行所有导航,它工作得很好。我只在这个 OnBackPressedCallback
中得到这个错误,并且只有当用户导航回到实现它的片段时。
如果您需要查看我的更多代码,请告诉我。
您可能 运行 遇到片段旧实例泄漏的问题。此外,将创建的视图存储在另一个变量(如 fragmentView
)中也不是一个好习惯。总而言之,您的 onCreateView
实施做了太多与其目的无关的事情。
我建议将功能拆分为相关的 life-cycle 方法并直接在回调中使用 fragment.view
。为了避免 运行 出现未附加视图的问题,您可以使用 life-cycle.
绑定和取消绑定回调
class PatientInfoFragment: Fragment() {
private val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Navigation.findNavController(view).navigate(R.id.action_patientInfoFragment_to_patientsList)
}
}
override fun onCreate(
savedInstanceState: Bundle?
) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.patient_info_fragment, container, false)
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
if(Utils.connectedToInternet()){
view.pastScreeningsButton.visibility = View.GONE
}
}
override fun onStart() {
super.onStart()
requireActivity().onBackPressedDispatcher.addCallback(callback)
}
override fun onStop() {
callback.remove()
super.onStop()
}
}
回调 life-cycle 绑定可以与片段绑定,作为生命周期所有者调用另一个 addCallback(LifecycleOwner, OnBackPressedCallback)
。
此外,您可以查看 Android KTX and Kotlin Android Extensions 以简化您的实施。
将您的代码移至 onViewCreated
并传递覆盖方法提供的 view
:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Navigation.findNavController(view).navigate(R.id.action_patientInfoFragment_to_patientsList)
}
})
}
如果这也不起作用,请将 .navigate()
替换为 popBastack(R.id.framgment_where_you_want to go, false)
,以防您之前的片段留在 backStack
我在 OnBackPressedCallback 中收到 does not have a NavController set
错误。这是代码
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
fragmentView = inflater.inflate(R.layout.patient_info_fragment, container, false)
if(Utils.connectedToInternet()){
fragmentView.pastScreeningsButton.visibility = View.GONE
}
requireActivity().onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Navigation.findNavController(fragmentView).navigate(R.id.action_patientInfoFragment_to_patientsList)
}
})
setHasOptionsMenu(true)
return fragmentView
}
当我回到实现它的片段时,我才收到这个错误。
我在主页片段中有 android:name="androidx.navigation.fragment.NavHostFragment"
。
澄清一下,我正在使用导航控制器围绕我的应用程序进行所有导航,它工作得很好。我只在这个 OnBackPressedCallback
中得到这个错误,并且只有当用户导航回到实现它的片段时。
如果您需要查看我的更多代码,请告诉我。
您可能 运行 遇到片段旧实例泄漏的问题。此外,将创建的视图存储在另一个变量(如 fragmentView
)中也不是一个好习惯。总而言之,您的 onCreateView
实施做了太多与其目的无关的事情。
我建议将功能拆分为相关的 life-cycle 方法并直接在回调中使用 fragment.view
。为了避免 运行 出现未附加视图的问题,您可以使用 life-cycle.
class PatientInfoFragment: Fragment() {
private val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Navigation.findNavController(view).navigate(R.id.action_patientInfoFragment_to_patientsList)
}
}
override fun onCreate(
savedInstanceState: Bundle?
) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.patient_info_fragment, container, false)
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
if(Utils.connectedToInternet()){
view.pastScreeningsButton.visibility = View.GONE
}
}
override fun onStart() {
super.onStart()
requireActivity().onBackPressedDispatcher.addCallback(callback)
}
override fun onStop() {
callback.remove()
super.onStop()
}
}
回调 life-cycle 绑定可以与片段绑定,作为生命周期所有者调用另一个 addCallback(LifecycleOwner, OnBackPressedCallback)
。
此外,您可以查看 Android KTX and Kotlin Android Extensions 以简化您的实施。
将您的代码移至 onViewCreated
并传递覆盖方法提供的 view
:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Navigation.findNavController(view).navigate(R.id.action_patientInfoFragment_to_patientsList)
}
})
}
如果这也不起作用,请将 .navigate()
替换为 popBastack(R.id.framgment_where_you_want to go, false)
,以防您之前的片段留在 backStack