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.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
@ -28,23 +29,26 @@ class FragmentViewBindingDelegate<T : ViewBinding>(
|
|||
private var binding: T? = null
|
||||
|
||||
init {
|
||||
fragment.lifecycle.addObserver(
|
||||
object : DefaultLifecycleObserver {
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
fragment.viewLifecycleOwnerLiveData.observe(
|
||||
fragment
|
||||
) { t ->
|
||||
t?.lifecycle?.addObserver(
|
||||
object : DefaultLifecycleObserver {
|
||||
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 {
|
||||
|
@ -58,7 +62,7 @@ class FragmentViewBindingDelegate<T : ViewBinding>(
|
|||
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