ViewBindingPropertyDelegate icon indicating copy to clipboard operation
ViewBindingPropertyDelegate copied to clipboard

How to correctly use a generic? View blank and onViewCreated() not called in Fragment nor Base

Open baggednismo opened this issue 1 year ago • 1 comments

I have an app with lots of fragments. It does not use view models. I have been using BaseFragment() : Fragment() as I need onCreateView() and onViewCreated() to do all of the same stuff in every view (set entry animations and add an animation delay for the transitions).

Following issue tracked previously here

I attempt to setup a new BaseVBFragment as such

abstract class BaseVBFragment<VB : ViewBinding>(viewBindingClass: Class<VB>) : Fragment() {

    protected val binding: VB by viewBinding(viewBindingClass)

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Timber.d("-> onCreateView()")
        setHasOptionsMenu(true)
        setEntryAnimations()
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        Timber.d("-> onViewCreated()")
        super.onViewCreated(view, savedInstanceState)
        delayAnimation(view)
    }

    override fun onResume() {
        logFragmentAnalytics()
        super.onResume()
    }
}

I setup my Fragment as such

class MyFragment : BaseVBFragment<MyFragmentBinding>(MyFragmentBinding::class.java) {
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        Timber.d("-> onViewCreated()")
        super.onViewCreated(view, savedInstanceState)
    }
    
    override fun onResume() {
        Timber.d("-> onResume()")
        super.onResume()

        // Can't access the Fragment View's LifecycleOwner for MyFragment{f4db0e9} when getView() is null i.e., before onCreateView() or after onDestroyView()
        observable.observe(viewLifecycleOwner) { /* do something on event */ }
    }

}

So with the error of not being able to access viewLifecycleOwner in onResume(), I moved that to MyFragment.onViewCreated()

This resolved the hard error but the view is completely blank. Looking at logs, MyFragment nor BaseVBFragment runs onViewCreated().

ActivityExtensionsKt                      D  -> hideSoftKeyboard()
BaseVBFragment                            D  -> onCreateView()
UpdateEmai...ssFragment                   D  -> onResume()
FragmentExtensionsKt                      D  -> logFragmentAnalytics()
FrameEvents                               E  updateAcquireFence: Did not find frame.
FrameEvents                               E  updateAcquireFence: Did not find frame.
FrameEvents                               E  updateAcquireFence: Did not find frame.
...

baggednismo avatar Feb 07 '24 17:02 baggednismo

Hi. I didn't find where you access ViewBinding instance in your code. The most common mistake is accessing it in callback of async calls. Before that you need to check that you view is still exists:

class AnyFragment : Fragment {

    fun anyFuncation() {
         // Start operation or subscribe on Flow/LiveData/Observable
         // that call callback async
         source.doOnResult {
             if([email protected] != null) {
                 //do operations using ViewBinding instance
             }
         }
    }
}

kirich1409 avatar May 13 '24 05:05 kirich1409