Architecture: Handling UI events - MAD Skills

Поділитися
Вставка
  • Опубліковано 18 лис 2024

КОМЕНТАРІ • 55

  • @haykmkrtchyan7093
    @haykmkrtchyan7093 2 роки тому +8

    I have some questions.
    - Why we need a list of error messages?
    - In 9:13 if we'll update the _uiState, our view will observe and update the view again. So what if we have > 1 error messages inside the errorMessages list? Will it show the next error?

  • @StuartStirling10
    @StuartStirling10 2 роки тому +4

    Seems very complicated to do something that should be very simple. This is not an accessible framework. The existence of a SnackbarHostState suggests we also need one for AlertDialog or am I mistaken as I can't see one provided?

    • @chrislagos44
      @chrislagos44 Рік тому

      Kotlin complicated everything! And this UI layer as well.. haha

  • @teefahlah
    @teefahlah 2 роки тому +3

    If the VM emits HomeUiState will that not recompose the whole Composable? Why wouldn't it be better to split up UiState to multiple flows so the individual data is updating to the corresponding composable?

  • @SeanProctorT
    @SeanProctorT 2 роки тому +2

    I don't understand why scaffoldState is used as a key to the LaunchedEffect. Can you explain that?

  • @Caffeine81
    @Caffeine81 2 роки тому +1

    Thanks for the video! I think there is an error on the slide starting at minute 2:02? I think the composable in HomeRoute should be HomeScreenWithList, not HomeRoute again?

  • @gmk57
    @gmk57 2 роки тому +1

    `LaunchedEffect(errorMessageText, retryMessageText, scaffoldState)` in 7:29 looks like magic, could you please elaborate how it ensures "exactly once" semantics? Without a very good documentation we might get a lot of subtle bugs around it.
    BTW, this particular case with snackbars may be handled much easier by hoisting `snackBarHostState` to ViewModel. It's clever enough to start dismiss timer only when the app is in the foreground and restart it on configuration changes. Works like a charm. :)

  • @СергейВыскребцев
    @СергейВыскребцев 2 роки тому +2

    Thanks a lot for your lessons!😇

    • @AndroidDevelopers
      @AndroidDevelopers  2 роки тому +1

      It is certainly our pleasure! You can also find additional information by visiting our guide to app architecture at goo.gle/Architecture 🌠

  • @danieldesantomori4586
    @danieldesantomori4586 2 роки тому +1

    Hello everyone, I have a problem, WebView does not display png images, how can I fix it? I would be very grateful for your help

  • @chtiboss78
    @chtiboss78 2 роки тому +6

    Nice video. Thanks.
    Is it possible to have sources of this exemple in a github repo for example?

    • @manuelvicnt
      @manuelvicnt 2 роки тому +3

      Sure! You can find them in the Compose Jetnews sample: goo.gle/compose-samples-jetnews

    • @chtiboss78
      @chtiboss78 2 роки тому

      @@manuelvicnt thanks !

  • @SoulReaperDan1
    @SoulReaperDan1 2 роки тому +3

    I feel like you guys can significantly reduce the boiler plate here, it quickly grows out of control

  • @ruif3r
    @ruif3r 2 роки тому +1

    HomeUiState is a sealed class, but I didn't see child classes. Having child classes doesn't mean that you need an additional when block in the view?

    • @manuelvicnt
      @manuelvicnt 2 роки тому +2

      We simplified the actual code that can be found here: github.com/android/compose-samples/blob/main/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeViewModel.kt#L43

  • @hafizmohd013
    @hafizmohd013 Рік тому

    R.string.load_error (need context) in viewmodel. How you do that without context ? please reply my message

  • @l_a_h797
    @l_a_h797 Рік тому

    I have a question ... where can we buy those cute Android bots that are on the shelves?

  • @周寒-v8s
    @周寒-v8s 2 роки тому

    Is that Google think compose can replace view now?

  • @mpgcode
    @mpgcode 2 роки тому +5

    Why not use a Channel to emit one-shot events from the ViewModel to the View? You can collect it as a flow and avoid the whole part about telling the VM that the View has triggered the event (which seems redundant).
    The only downside I can think of is that it only allows for one subscriber at the time which can make it tricky if you have multiple sources that need to capture the view event.

    • @vengateshm2122
      @vengateshm2122 2 роки тому +2

      SharedFlow can also be used for one time event

    • @manuelvicnt
      @manuelvicnt 2 роки тому +2

      Channels no longer guarantees the delivery of the event from coroutines 1.4 (see github.com/Kotlin/kotlinx.coroutines/issues/2886), that's why it's something we cannot recommend. More info here: developer.android.com/jetpack/guide/ui-layer/events#other-use-cases

    • @mpgcode
      @mpgcode 2 роки тому

      @@vengateshm2122 The problem with SharedFlow is that when there are no subscribers any events sent are dropped and therefore lost, which means that if your UI is not subscribed to the flow (configuration changes, app backgrounded and the UI observing the flow using the new lifecycle APIs...) the events will get lost.
      That makes them not reliable to send events to the UI. Channels on the other hand deliver the events only once and if they have no subscribers they keep the event in memory until a new subscriber appears and delivers the event to it only once (which makes them perfect for UI events from VM to View in my opinion).

    • @Dimezis
      @Dimezis 2 роки тому +1

      Channels are often not convenient with Compose, because any recomposition will make that one-shot side effect disappear, since it's consumed only once. This also makes impossible to, for example, show a dialog, rotate the screen and keep the dialog on the screen. You need to persist the dialog state for that, and with Channel the dialog will disappear after rotation.

    • @mpgcode
      @mpgcode 2 роки тому +1

      @@manuelvicnt Thank you for pointing to the Github issue. What are the cases where an event could be lost when using a Channel?
      For what I can tell from your comments in Github, is that when the UI receives the event but the view gets recreated right before handling/processing it? (so the Channel has actually delivered the event but because the view recreated the event is effectively lost and you have no info if the event was executed or not from the view perspective?).
      I can also see you mentioning the filtering operator which makes sense because the Channel would have effectively delivered the event but the view would have filtered it out. However I guess that as long as you remember that and you don't filter out events that you don't want to lose you should be safe.
      Any other examples you can think of?

  • @aleksandrurzhumtsev3983
    @aleksandrurzhumtsev3983 2 роки тому +5

    Instead of errorMesseges[0] you can use errorMesseges.first()

  • @XxJorx14xX
    @XxJorx14xX 2 роки тому

    Could I use rememberCoroutineScope() instead of LaunchedEffect in the scenario proposed in the video 7:26? What differences are there between these two APIs in this case?

    • @jatinvashisht4293
      @jatinvashisht4293 2 роки тому +3

      RememberCoroutineScope should now be used directly in composable function, as we have no control over how many times the state will re-compose, but launched effect takes care of it, the block inside the launched effect will only get triggered when its keys changes or the logic inside block gets triggered.
      So Launched effect is better option than RememberCoroutineScope

  • @kalidsherefuddin
    @kalidsherefuddin Рік тому

    Thanks

  • @chrislagos44
    @chrislagos44 Рік тому

    all these lines of codes to filter string resources in order to send notifications and snack messages. How about a switch structure in good ole Java that checks for the string resource and then easily determine whether a notification or snack message is needed.

  • @ЕленаБелашова-ц2ф
    @ЕленаБелашова-ц2ф 2 роки тому

    Love MAD Skills!!

  • @mehdi-vl5nn
    @mehdi-vl5nn Рік тому

    where is the model?

  • @bakytbeckk
    @bakytbeckk 2 роки тому +3

    I'd prefer to emit ui state with 3 different flows instead of single 'uiState'. So when, for ex., 'loading' is changed, I emit the new value for only 'loading'. The same for 'errorMessages' and 'searchInput'.
    I understand that there may be case when 2 or more properties should be updated at once. In this case I agree that it is better to emit state via single 'uiState' property. Is there any other pros for single 'uiState' flow?

    • @manuelvicnt
      @manuelvicnt 2 роки тому

      Exposing multiple streams of data is ok as long as they provide unrelated data to the UI, otherwise, you could create inconsistent UIs if those streams are out of sync. More info here: developer.android.com/jetpack/guide/data-layer#additional-considerations

    • @bakytbeckk
      @bakytbeckk 2 роки тому

      ​@@manuelvicnt Thanks for sharing. I discussed it with my colleague about it.
      We came to that using multiple flows increases the possibility of errors as you've mentioned. And it requires more attention. So it is better to use single state flow.

  • @star-warsien
    @star-warsien 2 роки тому +1

    compose and kotlin... Gotta make it a point to learn these soon. Problem is my company is very Java centric so no time to do it.

  • @petarnestorov1284
    @petarnestorov1284 2 роки тому +3

    How hard is for Google to use native speakers when making these videos? The presenter does not need to be a Software engineer (they use scripts anyway), the main purpose is to understand what you are trying to explain to us. Why add another layer of complexity when we have to struggle to understand what words exactly he is saying?
    P.S. The content is good! :)

  • @АлександраПантелеева-п7ъ

    Большое спасибо автору, классное видео)

  • @МиланаСкворцова-г3и

    Спасибо автору,классно видео

  • @Nekrull
    @Nekrull 2 роки тому +2

    In my code, I use a LaunchedEffect(vm) (where vm is the viewmodel) to observe a mutableSharedFlow which contains sealed classes that describe events the ViewModel wants the UI to take ShowDialog,NavigateToScreen, ShowSnackbar etc. and since it is a mutableSharedFlow , as soon as it is collected it is removed from the flow and it won't be executed again
    is that better or worse than having the ui events as shown above and sending back to the viewmodel events such as DialogShown, NavigatedToScreen or SnackbarShown?

    • @s-w
      @s-w 2 роки тому +2

      It does seem like an unneeded step to need the ui to notify the vm to remove the state.

    • @manuelvicnt
      @manuelvicnt 2 роки тому

      With SharedFlow you need to be careful as events can be "emitted" without the consumer being listening, if that happens, the event is lost. The UI doesn't always need to notify the ViewModel that the event was handled, that's only needed when another state change happens on that screen (in this case, the message being displayed is another state change). Here in the docs, we talk about different use cases and APIs, and why we recommend this approach: developer.android.com/jetpack/guide/ui-layer/events#other-use-cases

    • @Nekrull
      @Nekrull 2 роки тому

      @@manuelvicnt You are right about shared flow, I used to use SingleLiveEvent for such calls , and I've been trying to make a SingleMutableStateFlow that will behave the same for UI calls.
      Thank you for the link I will read it, but from the experience I got using compose with MVI in the project I am working currently, I always need to notify the VM that the event was handled (at least before I switched to shared flow) otherwise events would trigger again and again, because the state would still have in it that , for example, the user wants to navigate to the login screen, so if another part of the state changes , it will trigger the event again if I don't clear it. Am I missing something?

    • @s-w
      @s-w 2 роки тому

      @@manuelvicnt Thanks, I'll check the link out!

  • @Shakenbeer
    @Shakenbeer 2 роки тому +3

    That's ugly and doesn't solve the issue, when event is not UI related.

  • @keviyangaming2.093
    @keviyangaming2.093 2 роки тому +3

    Hi

  • @heshansandeepa9471
    @heshansandeepa9471 2 роки тому +1

    Awesome

  • @zakariasadikii
    @zakariasadikii 2 роки тому

    How can i get android figure like do you have

    • @manuelvicnt
      @manuelvicnt 2 роки тому +1

      I got them from here! www.deadzebra.com/project/android-collectibles/ :D

    • @zakariasadikii
      @zakariasadikii 2 роки тому

      @@manuelvicnt thanks it's cool =D

  • @arashthi9582
    @arashthi9582 2 роки тому +3

    hi

  • @jonneymendoza
    @jonneymendoza Рік тому

    No need to have te homeRoute composable

  • @HallEdsonBoss
    @HallEdsonBoss 2 роки тому +1

    Ok

  • @marcecc2011
    @marcecc2011 2 роки тому

    In my code, ha