これは、@ Shahab Rauf が示唆したのと同じ答えです。余分なことは、子フラグメントではなく BaseFragment にのみ Databinding を含めて onCreateView を実装することだけです。また、BaseFragment の onViewCreated() で navController を初期化します。
ベースフラグメント
abstract class BaseFragment<T : ViewDataBinding, VM : BaseViewModel<UiState>> : Fragment() {
protected lateinit var binding: T
var hasInitializedRootView = false
private var rootView: View? = null
protected abstract val mViewModel: ViewModel
protected lateinit var navController: NavController
fun getPersistentView(
inflater: LayoutInflater?,
container: ViewGroup?,
savedInstanceState: Bundle?,
layout: Int
): View? {
if (rootView == null) {
binding = DataBindingUtil.inflate(inflater!!, getFragmentView(), container, false)
//setting the viewmodel
binding.setVariable(BR.mViewModel, mViewModel)
// Inflate the layout for this fragment
rootView = binding.root
} else {
// Do not inflate the layout again.
// The returned View of onCreateView will be added into the fragment.
// However it is not allowed to be added twice even if the parent is same.
// So we must remove rootView from the existing parent view group
// (it will be added back).
(rootView?.getParent() as? ViewGroup)?.removeView(rootView)
}
return rootView
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? = getPersistentView(inflater, container, savedInstanceState, getFragmentView())
//this method is used to get the fragment layout file
abstract fun getFragmentView(): Int
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
}
}
HomeFragment (BaseFragment を拡張している任意のフラグメント)
class HomeFragment : BaseFragment<HomeFragmentBinding, HomeViewModel>(),
RecycleViewClickListener {
override val mViewModel by viewModel<HomeViewModel>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (!hasInitializedRootView) {hasInitializedRootView = true
setListeners()
loadViews()
--------
}