• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

<lambda>null1 package com.airbnb.lottie.samples.utils
2 
3 import android.os.Handler
4 import android.os.Looper
5 import android.view.View
6 import androidx.fragment.app.Fragment
7 import androidx.lifecycle.DefaultLifecycleObserver
8 import androidx.lifecycle.Lifecycle
9 import androidx.lifecycle.LifecycleOwner
10 import androidx.viewbinding.ViewBinding
11 import kotlin.properties.ReadOnlyProperty
12 import kotlin.reflect.KProperty
13 
14 /**
15  * Create bindings for a view similar to bindView.
16  *
17  * To use, just call
18  * private val binding: FHomeWorkoutDetailsBinding by viewBinding()
19  * with your binding class and access it as you normally would.
20  */
21 inline fun <reified T : ViewBinding> Fragment.viewBinding() = FragmentViewBindingDelegate(T::class.java, this)
22 
23 class FragmentViewBindingDelegate<T : ViewBinding>(
24     bindingClass: Class<T>,
25     val fragment: Fragment
26 ) : ReadOnlyProperty<Fragment, T> {
27     private val clearBindingHandler by lazy(LazyThreadSafetyMode.NONE) { Handler(Looper.getMainLooper()) }
28     private var binding: T? = null
29 
30     private val bindMethod = bindingClass.getMethod("bind", View::class.java)
31 
32     init {
33         fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
34             viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
35 
36                 override fun onDestroy(owner: LifecycleOwner) {
37                     // Lifecycle listeners are called before onDestroyView in a Fragment.
38                     // However, we want views to be able to use bindings in onDestroyView
39                     // to do cleanup so we clear the reference one frame later.
40                     clearBindingHandler.post { binding = null }
41                 }
42             })
43         }
44     }
45 
46     @Suppress("UNCHECKED_CAST")
47     override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
48         binding?.let { return it }
49 
50         val lifecycle = fragment.viewLifecycleOwner.lifecycle
51         if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
52             error("Cannot access view bindings. View lifecycle is ${lifecycle.currentState}!")
53         }
54 
55         binding = bindMethod.invoke(null, thisRef.requireView()) as T
56         return binding!!
57     }
58 }
59