Skip to content

Commit ef27516

Browse files
author
Yoga C. Pranata
committed
fix(fragment): Fix crash Can't access the Fragment View's LifecycleOwner when getView() is null when checking the fragment lifecycle using lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)
1 parent 75c5315 commit ef27516

1 file changed

Lines changed: 31 additions & 23 deletions

File tree

android-viewbinding/src/main/java/android/viewbinding/library/fragment/FragmentBinding.kt

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import androidx.fragment.app.Fragment
55
import androidx.lifecycle.DefaultLifecycleObserver
66
import androidx.lifecycle.Lifecycle
77
import androidx.lifecycle.LifecycleOwner
8+
import androidx.lifecycle.Observer
89
import androidx.viewbinding.ViewBinding
910
import kotlin.properties.ReadOnlyProperty
1011
import kotlin.reflect.KProperty
1112

1213
/**
13-
* Updated by Yoga C. Pranata on 06/05/2021.
14+
* Updated by Yoga C. Pranata on 04/12/2023.
1415
* Android Engineer
1516
*
1617
* How to use:
@@ -29,52 +30,59 @@ class FragmentViewBindingDelegate<T : ViewBinding>(
2930
private val fragment: Fragment
3031
) : ReadOnlyProperty<Fragment, T> {
3132

33+
3234
/**
3335
* initiate variable for binding view
3436
*/
3537
private var binding: T? = null
3638

39+
3740
/**
3841
* get the bind method from View class
3942
*/
4043
private val bindMethod = bindingClass.getMethod("bind", View::class.java)
4144

42-
@Suppress("UNCHECKED_CAST")
43-
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
44-
binding?.let { return it }
4545

46-
/**
47-
* Adding observer to the fragment lifecycle
48-
*/
46+
/**
47+
* Adding observer to the fragment lifecycle
48+
*/
49+
init {
4950
fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
50-
override fun onCreate(owner: LifecycleOwner) {
51-
fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
52-
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
53-
override fun onDestroy(owner: LifecycleOwner) {
54-
/**
55-
* Clear the binding when Fragment lifecycle called the onDestroy
56-
*/
57-
binding = null
58-
}
59-
})
51+
val viewLifecycleOwnerObserver = Observer<LifecycleOwner?> { owner ->
52+
if (owner == null) {
53+
binding = null
6054
}
6155
}
56+
override fun onCreate(owner: LifecycleOwner) {
57+
fragment.viewLifecycleOwnerLiveData.observeForever(viewLifecycleOwnerObserver)
58+
}
59+
60+
override fun onDestroy(owner: LifecycleOwner) {
61+
fragment.viewLifecycleOwnerLiveData.removeObserver(viewLifecycleOwnerObserver)
62+
}
6263
})
64+
}
65+
66+
@Suppress("UNCHECKED_CAST")
67+
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
68+
69+
binding?.let {
70+
if(it.root === thisRef.view) {
71+
return it
72+
}
73+
}
6374

6475

6576
/**
66-
* Checking the fragment lifecycle
77+
* Checking the fragment's view
6778
*/
68-
val lifecycle = fragment.viewLifecycleOwner.lifecycle
69-
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
70-
error("Cannot access view bindings. View lifecycle is ${lifecycle.currentState}!")
71-
}
79+
val view = thisRef.view ?: error("Should not attempt to get bindings when the Fragment's view is null.")
7280

7381

7482
/**
7583
* Bind layout
7684
*/
77-
val invoke = bindMethod.invoke(null, thisRef.requireView()) as T
85+
val invoke = bindMethod.invoke(null, view) as T
7886

7987
return invoke.also { this.binding = it }
8088
}

0 commit comments

Comments
 (0)