0

I have a ParentFragment and a ChildFragment that extends from it. I placed a log in onCreateView method of both fragments. But ParentFragment's onCreateView is being called last.

However, the same parent-child relationship between activities is producing the expected result. Parent activities onCreate is being called first and then child activity's onCreate.

ParentFragment

abstract class ParentFragment<T: ViewDataBinding>: Fragment(){

    @LayoutRes
    abstract fun getLayoutResId(): Int

    protected lateinit var binding: T


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Log.d("-----------", "onCreateView ParentFragment")
        return DataBindingUtil.inflate<T>(inflater, getLayoutResId(), container, false).apply { binding = this }.root
    }

ChildFragment

class ChildFragment: ParentFragment<FragmentChildBinding>() {

    @LayoutRes
    override fun getLayoutResId() = R.layout.fragment_child

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        Log.d("-----------", "onCreateView ChildFragment")

        return inflater.inflate(R.layout.fragment_child, container, false)
    }

Result for Fragments:

2019-12-10 10:54:28.054 32450-32450/blabla.yeahyeah D/-----------: onCreateView ChildFragment
2019-12-10 10:54:28.054 32450-32450/blabla.yeahyeah D/-----------: onCreateView ParentFragment

Result for Activities:

2019-12-10 10:54:27.796 32450-32450/blabla.yeahyeah D/-----------: onCreate ParentActivity
2019-12-10 10:54:27.931 32450-32450/blabla.yeahyeah D/-----------: onCreate ChildActivity

Can you please help with this? Am I missing something or is it an expected behavior?

The reason why I am overriding onCreateView is that I am trying to connect my viewModel to my binding in ChildFragment like this:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        Log.d("-----------", "onCreateView ChildFragment")

        val viewModel = getViewModel()
        binding.viewModel = viewModel //CRASH HAPPENING HERE. THIS VARIABLE IS NOT INITIALIZED
        binding.lifecycleOwner = this

        return binding.root
    }

Currently, I am getting crash becuse binding variable is not initialized when I access it from ChildFragment. Since this variable needs to be initialized in ParentFragment and ParentFragment is being called after ChildFragment, I amgetting crash as I understood.

Azizjon Kholmatov
  • 1,136
  • 1
  • 13
  • 26
  • 1
    Why do you override `onCreateView()` in child fragment anyway? You're already doing data binding in parent's `onCreateView()`. – Jeel Vankhede Dec 10 '19 at 06:57
  • @JeelVankhede explained why I am doing this. Check out the question again please. – Azizjon Kholmatov Dec 10 '19 at 07:18
  • 1
    Try your initialization in `onViewCreated()` method, it's subsequent call after `onCreateView()`, in this method your binding object would not be null. – Jeel Vankhede Dec 10 '19 at 07:39
  • @JeelVankhede Yes it helped. Thanks. How can I optimize my code so that I do not need to write this boilerplate code in every child fragment? – Azizjon Kholmatov Dec 10 '19 at 08:34
  • Your structure seems pretty strait forward to me. Just make sure that any code common to all fragments relies on parent fragment rather than all of child. Just let me know what are other boilerplate code! – Jeel Vankhede Dec 10 '19 at 10:24
  • @JeelVankhede well I had some issues with that. Could you please have a look at this. https://stackoverflow.com/questions/59279430/optimizing-parent-fragment-for-viewmodel-and-databinding-in-order-to-avoid-boile – Azizjon Kholmatov Dec 11 '19 at 05:35

0 Answers0