|
1 | 1 | package com.redmadrobot.extensions.viewbinding
|
2 | 2 |
|
3 |
| -import android.os.Handler |
4 |
| -import android.os.Looper |
5 | 3 | import androidx.fragment.app.Fragment
|
6 | 4 | import androidx.lifecycle.Lifecycle
|
| 5 | +import androidx.lifecycle.Lifecycle.Event.ON_DESTROY |
| 6 | +import androidx.lifecycle.Lifecycle.State.INITIALIZED |
7 | 7 | import androidx.lifecycle.LifecycleEventObserver
|
8 | 8 | import androidx.lifecycle.LifecycleOwner
|
9 | 9 | import androidx.viewbinding.ViewBinding
|
@@ -43,28 +43,43 @@ internal class ViewBindingDelegate<VB : ViewBinding> constructor(
|
43 | 43 | ) : ReadOnlyProperty<Any?, VB>, LifecycleEventObserver {
|
44 | 44 |
|
45 | 45 | private var binding: VB? = null
|
46 |
| - private val handler = Handler(Looper.getMainLooper()) |
| 46 | + |
| 47 | + private val fragmentViewNotDestroyed: Boolean |
| 48 | + get() = fragment.viewLifecycleOwner.lifecycle.currentState.isAtLeast(INITIALIZED) |
47 | 49 |
|
48 | 50 | init {
|
49 | 51 | fragment.viewLifecycleOwnerLiveData.observe(fragment) {
|
50 | 52 | it.lifecycle.addObserver(this)
|
51 | 53 | }
|
52 | 54 | }
|
53 | 55 |
|
54 |
| - override fun getValue(thisRef: Any?, property: KProperty<*>): VB = binding ?: obtainBinding() |
| 56 | + override fun getValue(thisRef: Any?, property: KProperty<*>): VB { |
| 57 | + checkFragmentViewNotChanged() |
| 58 | + return binding ?: obtainBinding() |
| 59 | + } |
| 60 | + |
| 61 | + /** |
| 62 | + * In some cases [Fragment] can change view without triggering [ON_DESTROY] on the old view. |
| 63 | + * So we should check that bound view is equal to fragment view. |
| 64 | + */ |
| 65 | + private fun checkFragmentViewNotChanged() { |
| 66 | + val boundView = binding?.root ?: return |
| 67 | + if (boundView != fragment.view) binding = null |
| 68 | + } |
55 | 69 |
|
56 | 70 | private fun obtainBinding(): VB {
|
57 | 71 | val view = checkNotNull(fragment.view) {
|
58 | 72 | "ViewBinding is only valid between onCreateView and onDestroyView."
|
59 | 73 | }
|
60 |
| - return viewBindingClass.bind(view) |
61 |
| - .also { binding = it } |
| 74 | + return viewBindingClass.bind(view).also { |
| 75 | + binding = it.takeIf { fragmentViewNotDestroyed } |
| 76 | + } |
62 | 77 | }
|
63 | 78 |
|
64 | 79 | override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
65 |
| - if (event == Lifecycle.Event.ON_DESTROY) { |
| 80 | + if (event == ON_DESTROY) { |
66 | 81 | source.lifecycle.removeObserver(this)
|
67 |
| - handler.post { binding = null } |
| 82 | + binding = null |
68 | 83 | }
|
69 | 84 | }
|
70 | 85 | }
|
0 commit comments