Android LiveData рдШрдЯрдирд╛рдПрдБ

LiveData рдЖрдкрдХреЗ рдбреЗрдЯрд╛ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рдЬреАрд╡рди рдЪрдХреНрд░ (LifecycleOwner, рдЖрдорддреМрд░ рдкрд░ рдПрдХ Fragment рдпрд╛ рдЧрддрд┐рд╡рд┐рдзрд┐) рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рдиреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рдЙрдкрдХрд░рдг рд╣реИред

рдЖрдорддреМрд░ рдкрд░, LiveData рдХреЛ ViewModel рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЗ UI рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдХреНрд╕рд░, рдПрдХ ViewModel рдПрдХ LifecycleOwner рдмрдЪ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдПрдХ LiveData рд╕реНрдерд┐рддрд┐ рдмрдирд╛рдП рд░рдЦ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рддрдВрддреНрд░ рдЙрдкрдпреБрдХреНрдд рд╣реИ рдЬрдм рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдХреБрдЫ рд╕рдордп рдмрд╛рдж рдЗрд╕реЗ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рджред

рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рдШрдЯрдирд╛рдУрдВ рдХреЗ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рди рдХрд┐ рд░рд╛рдЬреНрдпреЛрдВ рдХрд╛? рдФрд░ рдпрд╣ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЬреАрд╡рди рдЪрдХреНрд░ (LifecycleOwner) рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдХреЗ рдмрд╛рдж рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдмрд╢рд░реНрддреЗ рдХрд┐ LifecycleOwner рдЕрднреА рднреА рдЬреАрд╡рд┐рдд рд╣реИ, рд╕рдХреНрд░рд┐рдп рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╣реИрдВ, рдФрд░ рдЕрдкрдиреЗ UI рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рдпрджрд┐ рд╣рдо LiveData рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж, рдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдирдП рдЧреНрд░рд╛рд╣рдХ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред рдЙрди рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬреЛ рдЦреБрдж рдХреЛ рдХреБрдЫ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдбреЗрдЯрд╛ рдХреЛ LiveData рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреЛрдб рдЗрд╕ рддрд░рд╣:

Observer { handle(it) yourViewModel.liveData.value = null } 

рд▓реЗрдХрд┐рди рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдХрдИ рдиреБрдХрд╕рд╛рди рд╣реИрдВ рдФрд░ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рдПрдХ рдШрдЯрдирд╛ рддрдВрддреНрд░ рд░рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐:

  1. рдХреЗрд╡рд▓ рд╕рдХреНрд░рд┐рдп рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ
  2. рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рд╕рдордп рдкрд┐рдЫрд▓реЗ рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ,
  3. рдЗрд╡реЗрдВрдЯ рдХреА рдЖрдЧреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд▓реЗ рд╣реБрдП рдзреНрд╡рдЬ рдХреЛ рд╕рд╣реА рдкрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред

рдореИрдВрдиреЗ MutableLiveEvent рдХреНрд▓рд╛рд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдЧреБрдг рд╣реИрдВ рдФрд░ рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп LiveData рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

 //   EventArgs        class MyIntEventArgs(data: Int) : EventArgs<Int>(data) //  viewModel class MainViewModel : ViewModel() { private val myEventMutable = MutableLiveEvent<MyIntEventArgs>() val myEvent = myEventMutable as LiveData<MyIntEventArgs> fun sendEvent(data: Int) { myEventMutable.value = MyIntEventArgs(data) } } val vm = ViewModelProviders.of(this).get(MainViewModel::class.java) vm.myEvent.observe(this, Observer { //   /* *   ,    , *      ,   handled = true */ it.handled = true }) 

рд╕рднреА рдХреЛрдб GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ , рдФрд░ рдиреАрдЪреЗ рдореИрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред

 class MutableLiveEvent<T : EventArgs<Any>> : MutableLiveData<T>() { internal val observers = ArraySet<PendingObserver<in T>>() @MainThread override fun observe(owner: LifecycleOwner, observer: Observer<in T>) { val wrapper = PendingObserver(observer) observers.add(wrapper) super.observe(owner, wrapper) } override fun observeForever(observer: Observer<in T>) { val wrapper = PendingObserver(observer) observers.add(wrapper) super.observeForever(observer) } @MainThread override fun removeObserver(observer: Observer<in T>) { when (observer) { is PendingObserver -> { observers.remove(observer) super.removeObserver(observer) } else -> { val pendingObserver = observers.firstOrNull { it.wrappedObserver == observer } if (pendingObserver != null) { observers.remove(pendingObserver) super.removeObserver(pendingObserver) } } } } @MainThread override fun setValue(event: T?) { observers.forEach { it.awaitValue() } super.setValue(event) } } 

рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ MutableLiveEvent рд╡рд░реНрдЧ рдХреЗ рдЕрдВрджрд░, рдЕрд╡рд▓реЛрдХрди рдФрд░ рдЕрд╡рд▓реЛрдХрди рд╡рд┐рдзрд┐ рдореЗрдВ, рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЖрдВрддрд░рд┐рдХ рд╡рд░реНрдЧ PendingObserver рдореЗрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдХреЛ рд▓рдкреЗрдЯреЗрдВ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рд▓рдВрдмрд┐рдд рдзреНрд╡рдЬ рд╕рддреНрдп рдкрд░ рд╕реЗрдЯ рд╣реИ рдФрд░ рдШрдЯрдирд╛ рдЕрднреА рддрдХ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реБрдИ рд╣реИред

 internal class PendingObserver<T : EventArgs<Any>>(val wrappedObserver: Observer<in T>) : Observer<T> { private var pending = false override fun onChanged(event: T?) { if (pending && event?.handled != true) { pending = false wrappedObserver.onChanged(event) } } fun awaitValue() { pending = true } } 

PendingObserver рдореЗрдВ, рд▓рдВрдмрд┐рдд рдзреНрд╡рдЬ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЧрд▓рдд рдкрд░ рд╕реЗрдЯ рд╣реИред рдпрд╣ рд╣рдорд╛рд░реА рд╕реВрдЪреА рд╕реЗ рдЖрдЗрдЯрдо 2 (рдкреБрд░рд╛рдиреЗ рдбреЗрдЯрд╛ рдХреА рд╕реВрдЪрдирд╛ рди рджреЗрдВ) рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИред

рдФрд░ MutableLiveEvent рдореЗрдВ рдХреЛрдб

 override fun setValue(event: T?) { observers.forEach { it.awaitValue() } super.setValue(event) } 

рдкрд╣рд▓реЗ рд╕рд╣реА рдкрд░ рд▓рдВрдмрд┐рдд рд╕реЗрдЯ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдбреЗрдЯрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рджрд╛рд╡реЗ 1 рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИред (рдЕрд▓рд░реНрдЯ рдХреЗрд╡рд▓ рд╕рдХреНрд░рд┐рдп рдЧреНрд░рд╛рд╣рдХ)ред

рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдмрд╛рдд рдирд╣реАрдВ рдХреА рд╣реИ рд╡рд╣ рд╣реИ EventArgsред рдпрд╣ рд╡рд░реНрдЧ рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдШрдЯрдирд╛ рдХреЗ рдЖрдЧреЗ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг (рдХреНрд▓рд╛рдЬ 3) рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрднрд╛рд▓рд╛ рд╣реБрдЖ рдЭрдВрдбрд╛ рд╣реЛрддрд╛ рд╣реИред

 open class EventArgs<out T>(private val content: T?) { var handled: Boolean = false val data: T? get() { return if (handled) { null } else { content } } } 

рдпрд╣ рд╕рдм, рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

Source: https://habr.com/ru/post/hi468749/


All Articles