ViewBindingPropertyDelegate
ViewBindingPropertyDelegate copied to clipboard
How to correctly use a generic? View blank and onViewCreated() not called in Fragment nor Base
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.
...
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
}
}
}
}