elizarov
06/08/2020, 9:08 AMRx/Channel/Flow/LiveData
to deliver those events (comment in :thread-please: what you do instead).
1️⃣ Using an Event
wrapper class, adapting solution in the above story to coroutines.
2️⃣ Using a [buffered or rendezvous] Channel
for events, exposing it to the views either as Channel
or as a Flow
via receiveAsFlow()
extension.
3️⃣ Some other approach (comment in :thread-please:).gildor
06/08/2020, 9:15 AMMartin Nordholts
06/08/2020, 9:16 AMViewModel
contains a LiveData<MessageToShow>
field that our SnackBar implementation listens to via XML Data Binding, and clears upon close-button being clicked (also via XML Data Binding), or via timeout from within ViewModel.
The field can be set via a coroutine that runs within ViewModel scope.
For the “press back” use case:
ViewModel is not used at all since ViewModel is about data to be displayed, which is not really related to events (although of course, an event can mutate the ViewModel data, but for e.g. a “go back” event, no ViewModel data per-se is mutated. The point is that events are not stored within ViewModel, it’s only side effects of events that are stored)sindrenm
06/08/2020, 9:17 AMMutableStateFlow()
takes an initial value.gildor
06/08/2020, 9:21 AMpawegio
06/08/2020, 9:25 AMsindrenm
06/08/2020, 9:25 AMval viewEffects: StateFlow<Event<ViewEffect>?>
get() = _viewEffects
private val _viewEffects = MutableStateFlow<Event<ViewEffect>?>(null)
But I don't feel like events should ever be null
. 😛gildor
06/08/2020, 9:41 AMthis would work if we wanted it to “be the same” as LiveData in that regardLiveData doesn’t emit null if you subscribe without default value, so it’s not the same, it more like:
val viewEffects: StateFlow<Event<ViewEffect>>
get() = _viewEffects.mapNonNull()
Tho it still looks unnecessary to do with operatorflosch
06/08/2020, 9:45 AMgildor
06/08/2020, 9:49 AMkenkyee
06/08/2020, 10:11 AMstreetsofboston
06/08/2020, 11:38 AMEventFlow
, implementing Flow
by a Rendezvous Channel's receiveAsFlow()
. It has two methods/props: CoroutineScope.value: T
(only as a setter) and suspend fun postValue(v: T)
., both sending the providied value to the Channel.Drew Hamilton
06/08/2020, 11:53 AMelizarov
06/08/2020, 11:56 AMZach Klippenstein (he/him) [MOD]
06/08/2020, 12:30 PMdewildte
06/08/2020, 12:53 PMFlow
of events and stop collecting when the LifecycleOwner
is not in the correct state for handing the event.Adam Powell
06/08/2020, 1:38 PMLiveData
is a state type, not an event stream type. 1️⃣ is a hack to work around this without sorting out the difference between events and state in the app, which has been pretty harmful to the understanding of the whole space for a lot of people since it was written.henrikhorbovyi
06/08/2020, 1:56 PMgildor
06/08/2020, 2:20 PMrkeazor
06/08/2020, 3:20 PMhenrikhorbovyi
06/08/2020, 3:39 PMdewildte
06/09/2020, 1:13 PMAdam Powell
06/09/2020, 1:28 PMdewildte
06/09/2020, 1:56 PMBrendan Weinstein
06/11/2020, 6:59 PM