sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

How to make a difference between ViewStates with StateReducer? #294

Closed larten closed 6 years ago

larten commented 6 years ago

Hi,

In the mvi-sample project you make difference between ViewStates in the render method. It is good, because you change on the view only what changed in the state. But how can I solve it, if I'm using state reducer? I lose the information during reduce, but it would be nice to refresh only the changed UI parts.

I checked a few databinding solution and there it's easy to bind a part of view a part of data.

Sorry if it's not relevant to others, but currently this is my only problem and I try to keep the MVI solution in my apps :D

br, Larten

sockeqwe commented 6 years ago

Hey, I'm sorry but I don't b understand what you mean. Can you give me a concrete example

larten commented 6 years ago

Sure!

Here is a viewstate. The data and list properties are coming from different resources or refreshing in different times.

public class MyViewState {
    private boolean loading;
    private String data;
    private ArrayLis<MyObject> list;
    private Throwable throwable;
}

And here is the render method in the view:

@Override
    public void render(MyViewState viewState) {
        if(viewState.isLoading()) {
            // loading handling
        } else if(viewState.getError() != null) {
            // render data and list
        } else {
            // error handling
        }
    }

If I trigger an action (press button, anything) and refresh the data property in the viewstate with the reducer, I will also reload the UI part where I show the list property when I'm rendering.

sockeqwe commented 6 years ago

I'm really sorry but I still Don't understand what information you loose?

László Krasnyánszki notifications@github.com schrieb am Do., 14. Dez. 2017, 22:54:

Sure!

Here is a viewstate. The data and list properties are coming from different resources or refreshind in different time.

public class MyViewState { private boolean loading; private String data; private ArrayLis list; private Throwable throwable; }

And here is the render method in the view:

@Override public void render(MyViewState viewState) { if(viewState.isLoading()) { // loading handling } else if(viewState.getError() != null) { // render data and list } else { // error handling } }

If I trigger an action (press button, anything) and refresh the data property in the viewstate with the reducer, I will also reload the UI parth where I show the list property when I'm rendering.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/sockeqwe/mosby/issues/294#issuecomment-351847719, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjnro143wzmSybWYV6wqPmLE0-mekEVks5tAZklgaJpZM4RCskN .

larten commented 6 years ago

No it's okay, sorry for that and thank you for your time!

Here is an example: (but in the example contains only 3 states of viewstate (loading, data loaded and error) https://gist.github.com/larten/10c35f46a11d089e3f321d46aa40e04a

Every time when a state will be changed you will render all views again. Imagine, you have a data class with 20 fields and after some interactions, only one text field changed. Instead of updating one single TextView you will re-render all views.

I think it's unnecessary to update every view. We should update on the UI only what changed (like DiffUtil on RecyclerView). Maybe I should use subclasses of my EpisodeDetailsViewState for example and when I'm rendering I should make a difference depends on class. But it seems not too elegant solution. I try to find something like the ObservableField in the MVVM databinding solutions. When you change a property in the viewstate you notify the subscribed UI elements only, if the data changed.

sockeqwe commented 6 years ago

that has never been an issue for me and I just can recommend, that until it really gets an issue don't care about it ...

The only one operation that comes immediately into my mind which is expensive is setting text on a TextView because this will trigger a whole relayout of the text layout even if the text hasn't changed.

But again, unless it is really an issue, I wouldn't bother ... If this, however, becomes an issue someday, I would recommend to determine which UI widgets should be updated in the view layer, maybe manually with if else or a librarie like anvil can help