-
-
Save Zhuinden/ea3189198938bd16c03db628e084a4fa to your computer and use it in GitHub Desktop.
// https://github.com/Zhuinden/fragmentviewbindingdelegate-kt | |
import android.view.View | |
import androidx.fragment.app.Fragment | |
import androidx.lifecycle.DefaultLifecycleObserver | |
import androidx.lifecycle.Lifecycle | |
import androidx.lifecycle.LifecycleOwner | |
import androidx.lifecycle.Observer | |
import androidx.viewbinding.ViewBinding | |
import kotlin.properties.ReadOnlyProperty | |
import kotlin.reflect.KProperty | |
class FragmentViewBindingDelegate<T : ViewBinding>( | |
val fragment: Fragment, | |
val viewBindingFactory: (View) -> T | |
) : ReadOnlyProperty<Fragment, T> { | |
private var binding: T? = null | |
init { | |
fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { | |
val viewLifecycleOwnerLiveDataObserver = | |
Observer<LifecycleOwner?> { | |
val viewLifecycleOwner = it ?: return@Observer | |
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { | |
override fun onDestroy(owner: LifecycleOwner) { | |
binding = null | |
} | |
}) | |
} | |
override fun onCreate(owner: LifecycleOwner) { | |
fragment.viewLifecycleOwnerLiveData.observeForever(viewLifecycleOwnerLiveDataObserver) | |
} | |
override fun onDestroy(owner: LifecycleOwner) { | |
fragment.viewLifecycleOwnerLiveData.removeObserver(viewLifecycleOwnerLiveDataObserver) | |
} | |
}) | |
} | |
override fun getValue(thisRef: Fragment, property: KProperty<*>): T { | |
val binding = binding | |
if (binding != null) { | |
return binding | |
} | |
val lifecycle = fragment.viewLifecycleOwner.lifecycle | |
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) { | |
throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") | |
} | |
return viewBindingFactory(thisRef.requireView()).also { this.binding = it } | |
} | |
} | |
fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) = | |
FragmentViewBindingDelegate(this, viewBindingFactory) |
@gmk57 Oh these make sense. Thank you!
sounds like you are missing
val binding = binding
in youronViewCreated
OR you are actually accessing the view afteronDestroyView
and potentially have a memory leak in your app anyway.
Btw there is an updated version of this gist as a library in https://github.com/Zhuinden/fragmentviewbindingdelegate-kt
@Zhuinden what is the real reason behind val binding = binding
in most cases we directly access binding. is this required ? .
@manju23reddy I debugged a guy's code who had trouble with callbacks of a WebView running on a different thread and this was the fix, so I do do it in my code personally.
I've had to do a modification on this idea that allows us to use the binding right before it gets nullified.
An example scenario is when we need to null the adapter of a recyclerView when a fragment is destroyed. Using this gist will lead to a crash because the life cycle state DESTROYED
is set before any of the onDestroy*
methods are called inside the fragment, which causes the throw
in line 50 of this gist.
I've added an optional onDestroyListener
parameter to the class, ex:
class FragmentViewBindingDelegate<T : ViewBinding>(
val fragment: Fragment,
val viewBindingFactory: (View) -> T,
val onDestroyListener: () -> Unit = {}
) : ReadOnlyProperty<Fragment, T> {
Which is then used inside the observer's onDestroy
, ex:
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
onDestroyListener()
binding = null
}
})
This guarantees that any sync code inside that listener has access to the binding before it is null, which allows me to, for example, remove the adapter of a recyclerView when the fragment is destroyed.
@ParticleCore i did eventually move this code to a library in https://github.com/Zhuinden/fragmentviewbindingdelegate-kt because these oddities kept coming up inherited from Google's code so it made sense to version it instead.
Fatal Exception: java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView() at androidx.fragment.app.Fragment.getViewLifecycleOwner(Fragment.java:361) at net.example.company.utils.views.FragmentViewBindingDelegate.getValue(FragmentViewBindingDelegate.java:61) at net.example.company.views.smartdogtrainer.common.FragBlah.getBinding(FragBlah.java:80) at net.example.company.views.smartdogtrainer.common.FragBlah.visibilityConnectingContainer(FragBlah.java:295) at net.example.company.views.smartdogtrainer.common.FragBlah.resetVisibility(FragBlah.java:289) at net.example.company.views.smartdogtrainer.common.FragBlah.showErrorConnection(FragBlah.java:311) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection$lambda-8$lambda-7(FragBlah.java:332) at net.example.company.views.smartdogtrainer.common.FragBlah$$InternalSyntheticLambda$0$deef3459a1d7d120afdfd9de73e823d74825ffa0a9101b2fc6484805f55a8632$0.run$bridge(FragBlah.java:13) at android.app.Activity.runOnUiThread(Activity.java:7154) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection(FragBlah.java:331) at net.example.company.views.smartdogtrainer.common.FragBlah.access$performErrorConnection(FragBlah.java:63) at net.example.company.views.smartdogtrainer.common.FragBlah$sdtCollarScannerCallback$1.onStopScanning(FragBlah.java:120) at net.example.company.scanner.BleScanner.stopScanningForDevices(BleScanner.java:128) at net.example.company.scanner.BleScanner.durationTimeoutScanning(BleScanner.java:116) at net.example.company.scanner.BleScanner.access$durationTimeoutScanning(BleScanner.java:15) at net.example.company.scanner.BleScanner$durationScanningRunnable$1.run(BleScanner.java:52) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8595) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)And my delegate:
class FragmentViewBindingDelegate<T : ViewBinding>( val fragment: Fragment, val viewBindingFactory: (Fragment) -> T, val cleanUp: ((T?) -> Unit)? ) : ReadOnlyProperty<Fragment, T> { // A backing property to hold our value private var binding: T? = null init { fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { val viewLifecycleOwnerLiveDataObserver = Observer<LifecycleOwner?> { val viewLifecycleOwner = it ?: return@Observer viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { cleanUp?.invoke(binding) binding = null } }) } override fun onCreate(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.observeForever( viewLifecycleOwnerLiveDataObserver ) } override fun onDestroy(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.removeObserver( viewLifecycleOwnerLiveDataObserver ) } }) } override fun getValue( thisRef: Fragment, property: KProperty<*> ): T { val binding = binding if (binding != null) { return binding } val lifecycle = fragment.viewLifecycleOwner.lifecycle if (lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED).not()) { throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") } return viewBindingFactory(thisRef).also { this.binding = it } } } inline fun <T : ViewBinding> Fragment.viewBinding( crossinline viewBindingFactory: (View) -> T, noinline cleanUp: ((T?) -> Unit)? = null ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> viewBindingFactory(f.requireView()) }, cleanUp) inline fun <T : ViewBinding> Fragment.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T, noinline cleanUp: ((T?) -> Unit)? = null, ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> bindingInflater(f.layoutInflater) }, cleanUp) inline fun <T : ViewBinding> AppCompatActivity.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T ) = lazy(LazyThreadSafetyMode.NONE) { bindingInflater.invoke(layoutInflater) }
Have you found the cause of this error? I also encountered this error when implementing it in a fragment.
My code below:
override val binding by viewBinding {
rcData.adapter = null
}
Have you found the cause of this error? I also encountered this error when implementing it in a fragment. My code below: override val binding by viewBinding { rcData.adapter = null }
@chinh-phi In getValue, had to use thisRef instead of view: https://github.com/Drjacky/MVVMTemplate/blob/6b9a39454e9260b6d979ca5c02f633e5e2d4bd2d/presentation/src/main/kotlin/app/web/drjackycv/presentation/extension/Extensions.kt
Have you found the cause of this error? I also encountered this error when implementing it in a fragment. My code below: override val binding by viewBinding { rcData.adapter = null }
@chinh-phi In getValue, had to use thisRef instead of view: https://github.com/Drjacky/MVVMTemplate/blob/6b9a39454e9260b6d979ca5c02f633e5e2d4bd2d/presentation/src/main/kotlin/app/web/drjackycv/presentation/extension/Extensions.kt
Actually, it encounters an error when executing the following code even though onDestroyView has already been called:
binding.rvData.post {
binding.rvData.layoutManager?.scrollToPosition(0)
}
Do you know any way to fix it?. Thanks
Fatal Exception: java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView() at androidx.fragment.app.Fragment.getViewLifecycleOwner(Fragment.java:361) at net.example.company.utils.views.FragmentViewBindingDelegate.getValue(FragmentViewBindingDelegate.java:61) at net.example.company.views.smartdogtrainer.common.FragBlah.getBinding(FragBlah.java:80) at net.example.company.views.smartdogtrainer.common.FragBlah.visibilityConnectingContainer(FragBlah.java:295) at net.example.company.views.smartdogtrainer.common.FragBlah.resetVisibility(FragBlah.java:289) at net.example.company.views.smartdogtrainer.common.FragBlah.showErrorConnection(FragBlah.java:311) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection$lambda-8$lambda-7(FragBlah.java:332) at net.example.company.views.smartdogtrainer.common.FragBlah$$InternalSyntheticLambda$0$deef3459a1d7d120afdfd9de73e823d74825ffa0a9101b2fc6484805f55a8632$0.run$bridge(FragBlah.java:13) at android.app.Activity.runOnUiThread(Activity.java:7154) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection(FragBlah.java:331) at net.example.company.views.smartdogtrainer.common.FragBlah.access$performErrorConnection(FragBlah.java:63) at net.example.company.views.smartdogtrainer.common.FragBlah$sdtCollarScannerCallback$1.onStopScanning(FragBlah.java:120) at net.example.company.scanner.BleScanner.stopScanningForDevices(BleScanner.java:128) at net.example.company.scanner.BleScanner.durationTimeoutScanning(BleScanner.java:116) at net.example.company.scanner.BleScanner.access$durationTimeoutScanning(BleScanner.java:15) at net.example.company.scanner.BleScanner$durationScanningRunnable$1.run(BleScanner.java:52) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8595) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)And my delegate:
class FragmentViewBindingDelegate<T : ViewBinding>( val fragment: Fragment, val viewBindingFactory: (Fragment) -> T, val cleanUp: ((T?) -> Unit)? ) : ReadOnlyProperty<Fragment, T> { // A backing property to hold our value private var binding: T? = null init { fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { val viewLifecycleOwnerLiveDataObserver = Observer<LifecycleOwner?> { val viewLifecycleOwner = it ?: return@Observer viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { cleanUp?.invoke(binding) binding = null } }) } override fun onCreate(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.observeForever( viewLifecycleOwnerLiveDataObserver ) } override fun onDestroy(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.removeObserver( viewLifecycleOwnerLiveDataObserver ) } }) } override fun getValue( thisRef: Fragment, property: KProperty<*> ): T { val binding = binding if (binding != null) { return binding } val lifecycle = fragment.viewLifecycleOwner.lifecycle if (lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED).not()) { throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") } return viewBindingFactory(thisRef).also { this.binding = it } } } inline fun <T : ViewBinding> Fragment.viewBinding( crossinline viewBindingFactory: (View) -> T, noinline cleanUp: ((T?) -> Unit)? = null ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> viewBindingFactory(f.requireView()) }, cleanUp) inline fun <T : ViewBinding> Fragment.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T, noinline cleanUp: ((T?) -> Unit)? = null, ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> bindingInflater(f.layoutInflater) }, cleanUp) inline fun <T : ViewBinding> AppCompatActivity.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T ) = lazy(LazyThreadSafetyMode.NONE) { bindingInflater.invoke(layoutInflater) }Have you found the cause of this error? I also encountered this error when implementing it in a fragment. My code below: override val binding by viewBinding { rcData.adapter = null }
Stop trying to update views after the views are destroyed, check with if(isAdded()) {}
or cancel your task in onDestroyView
so that this doesn't happen.
You can also wrap it in a try-catch if you just want to ignore it.
Fatal Exception: java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView() at androidx.fragment.app.Fragment.getViewLifecycleOwner(Fragment.java:361) at net.example.company.utils.views.FragmentViewBindingDelegate.getValue(FragmentViewBindingDelegate.java:61) at net.example.company.views.smartdogtrainer.common.FragBlah.getBinding(FragBlah.java:80) at net.example.company.views.smartdogtrainer.common.FragBlah.visibilityConnectingContainer(FragBlah.java:295) at net.example.company.views.smartdogtrainer.common.FragBlah.resetVisibility(FragBlah.java:289) at net.example.company.views.smartdogtrainer.common.FragBlah.showErrorConnection(FragBlah.java:311) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection$lambda-8$lambda-7(FragBlah.java:332) at net.example.company.views.smartdogtrainer.common.FragBlah$$InternalSyntheticLambda$0$deef3459a1d7d120afdfd9de73e823d74825ffa0a9101b2fc6484805f55a8632$0.run$bridge(FragBlah.java:13) at android.app.Activity.runOnUiThread(Activity.java:7154) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection(FragBlah.java:331) at net.example.company.views.smartdogtrainer.common.FragBlah.access$performErrorConnection(FragBlah.java:63) at net.example.company.views.smartdogtrainer.common.FragBlah$sdtCollarScannerCallback$1.onStopScanning(FragBlah.java:120) at net.example.company.scanner.BleScanner.stopScanningForDevices(BleScanner.java:128) at net.example.company.scanner.BleScanner.durationTimeoutScanning(BleScanner.java:116) at net.example.company.scanner.BleScanner.access$durationTimeoutScanning(BleScanner.java:15) at net.example.company.scanner.BleScanner$durationScanningRunnable$1.run(BleScanner.java:52) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8595) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)And my delegate:
class FragmentViewBindingDelegate<T : ViewBinding>( val fragment: Fragment, val viewBindingFactory: (Fragment) -> T, val cleanUp: ((T?) -> Unit)? ) : ReadOnlyProperty<Fragment, T> { // A backing property to hold our value private var binding: T? = null init { fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { val viewLifecycleOwnerLiveDataObserver = Observer<LifecycleOwner?> { val viewLifecycleOwner = it ?: return@Observer viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { cleanUp?.invoke(binding) binding = null } }) } override fun onCreate(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.observeForever( viewLifecycleOwnerLiveDataObserver ) } override fun onDestroy(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.removeObserver( viewLifecycleOwnerLiveDataObserver ) } }) } override fun getValue( thisRef: Fragment, property: KProperty<*> ): T { val binding = binding if (binding != null) { return binding } val lifecycle = fragment.viewLifecycleOwner.lifecycle if (lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED).not()) { throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") } return viewBindingFactory(thisRef).also { this.binding = it } } } inline fun <T : ViewBinding> Fragment.viewBinding( crossinline viewBindingFactory: (View) -> T, noinline cleanUp: ((T?) -> Unit)? = null ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> viewBindingFactory(f.requireView()) }, cleanUp) inline fun <T : ViewBinding> Fragment.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T, noinline cleanUp: ((T?) -> Unit)? = null, ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> bindingInflater(f.layoutInflater) }, cleanUp) inline fun <T : ViewBinding> AppCompatActivity.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T ) = lazy(LazyThreadSafetyMode.NONE) { bindingInflater.invoke(layoutInflater) }Have you found the cause of this error? I also encountered this error when implementing it in a fragment. My code below: override val binding by viewBinding { rcData.adapter = null }
Stop trying to update views after the views are destroyed, check with
if(isAdded()) {}
or cancel your task inonDestroyView
so that this doesn't happen.You can also wrap it in a try-catch if you just want to ignore it.
i call:
binding.rvData.post {
binding.rvData.layoutManager?.scrollToPosition(0)
}
onViewCreated(). However, for some reason, it is not executed immediately but instead runs after onDestroyView is called.
=> crash
Do you have any way to fix it? Thanks
Fatal Exception: java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView() at androidx.fragment.app.Fragment.getViewLifecycleOwner(Fragment.java:361) at net.example.company.utils.views.FragmentViewBindingDelegate.getValue(FragmentViewBindingDelegate.java:61) at net.example.company.views.smartdogtrainer.common.FragBlah.getBinding(FragBlah.java:80) at net.example.company.views.smartdogtrainer.common.FragBlah.visibilityConnectingContainer(FragBlah.java:295) at net.example.company.views.smartdogtrainer.common.FragBlah.resetVisibility(FragBlah.java:289) at net.example.company.views.smartdogtrainer.common.FragBlah.showErrorConnection(FragBlah.java:311) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection$lambda-8$lambda-7(FragBlah.java:332) at net.example.company.views.smartdogtrainer.common.FragBlah$$InternalSyntheticLambda$0$deef3459a1d7d120afdfd9de73e823d74825ffa0a9101b2fc6484805f55a8632$0.run$bridge(FragBlah.java:13) at android.app.Activity.runOnUiThread(Activity.java:7154) at net.example.company.views.smartdogtrainer.common.FragBlah.performErrorConnection(FragBlah.java:331) at net.example.company.views.smartdogtrainer.common.FragBlah.access$performErrorConnection(FragBlah.java:63) at net.example.company.views.smartdogtrainer.common.FragBlah$sdtCollarScannerCallback$1.onStopScanning(FragBlah.java:120) at net.example.company.scanner.BleScanner.stopScanningForDevices(BleScanner.java:128) at net.example.company.scanner.BleScanner.durationTimeoutScanning(BleScanner.java:116) at net.example.company.scanner.BleScanner.access$durationTimeoutScanning(BleScanner.java:15) at net.example.company.scanner.BleScanner$durationScanningRunnable$1.run(BleScanner.java:52) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8595) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)And my delegate:
class FragmentViewBindingDelegate<T : ViewBinding>( val fragment: Fragment, val viewBindingFactory: (Fragment) -> T, val cleanUp: ((T?) -> Unit)? ) : ReadOnlyProperty<Fragment, T> { // A backing property to hold our value private var binding: T? = null init { fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { val viewLifecycleOwnerLiveDataObserver = Observer<LifecycleOwner?> { val viewLifecycleOwner = it ?: return@Observer viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { cleanUp?.invoke(binding) binding = null } }) } override fun onCreate(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.observeForever( viewLifecycleOwnerLiveDataObserver ) } override fun onDestroy(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.removeObserver( viewLifecycleOwnerLiveDataObserver ) } }) } override fun getValue( thisRef: Fragment, property: KProperty<*> ): T { val binding = binding if (binding != null) { return binding } val lifecycle = fragment.viewLifecycleOwner.lifecycle if (lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED).not()) { throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") } return viewBindingFactory(thisRef).also { this.binding = it } } } inline fun <T : ViewBinding> Fragment.viewBinding( crossinline viewBindingFactory: (View) -> T, noinline cleanUp: ((T?) -> Unit)? = null ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> viewBindingFactory(f.requireView()) }, cleanUp) inline fun <T : ViewBinding> Fragment.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T, noinline cleanUp: ((T?) -> Unit)? = null, ): FragmentViewBindingDelegate<T> = FragmentViewBindingDelegate(this, { f -> bindingInflater(f.layoutInflater) }, cleanUp) inline fun <T : ViewBinding> AppCompatActivity.viewInflateBinding( crossinline bindingInflater: (LayoutInflater) -> T ) = lazy(LazyThreadSafetyMode.NONE) { bindingInflater.invoke(layoutInflater) }Have you found the cause of this error? I also encountered this error when implementing it in a fragment. My code below: override val binding by viewBinding { rcData.adapter = null }
Stop trying to update views after the views are destroyed, check with
if(isAdded()) {}
or cancel your task inonDestroyView
so that this doesn't happen.
You can also wrap it in a try-catch if you just want to ignore it.i call: binding.rvData.post { binding.rvData.layoutManager?.scrollToPosition(0) } onViewCreated(). However, for some reason, it is not executed immediately but instead runs after onDestroyView is called. => crash Do you have any way to fix it? Thanks
You're using handler.post {}
, so it's possible for it to run after onDestroyView
.
@AndroidDeveloperLB There are two "flavors" of
DialogFragment
, they have different view lifecycle. You can find examples for both cases here.