Fix lifecycle handling bug (#3319)
Fragments can go `onCreate` -> `onCreateView` -> `onViewCreated` -> `onDestroyView` without transitioning through `onStart`. The previous code assumed `onStart` was always called. Se https://itnext.io/an-update-to-the-fragmentviewbindingdelegate-the-bug-weve-inherited-from-autoclearedvalue-7fc0a89fcae1
This commit is contained in:
parent
c6f7ecdb5b
commit
4a0251800d
1 changed files with 20 additions and 16 deletions
|
@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
@ -28,23 +29,26 @@ class FragmentViewBindingDelegate<T : ViewBinding>(
|
||||||
private var binding: T? = null
|
private var binding: T? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
fragment.lifecycle.addObserver(
|
fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||||
object : DefaultLifecycleObserver {
|
val viewLifecycleOwnerLiveDataObserver =
|
||||||
override fun onCreate(owner: LifecycleOwner) {
|
Observer<LifecycleOwner?> {
|
||||||
fragment.viewLifecycleOwnerLiveData.observe(
|
val viewLifecycleOwner = it ?: return@Observer
|
||||||
fragment
|
|
||||||
) { t ->
|
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||||
t?.lifecycle?.addObserver(
|
override fun onDestroy(owner: LifecycleOwner) {
|
||||||
object : DefaultLifecycleObserver {
|
binding = null
|
||||||
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 {
|
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
|
||||||
|
@ -58,7 +62,7 @@ class FragmentViewBindingDelegate<T : ViewBinding>(
|
||||||
throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
|
throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return viewBindingFactory(thisRef.requireView()).also { this@FragmentViewBindingDelegate.binding = it }
|
return viewBindingFactory(thisRef.requireView()).also { this.binding = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue