The View State
Our view layer gets its ToDoModel instances from the ViewState. This class aggregates all of the data necessary to render our three fragments. It includes:
- The list of models to display (as this sample app makes the tremendously simplifying assumption that the entire set of to-do items can be held in memory)
 - A 
booleanindicating whether the data has been loaded or not, so we can distinguish whether an empty list of models means “we have no to-do items” or “we have not yet loaded the to-do items” - A list of indices into the model data representing items that are selected, when the list fragment is in multi-select mode
 - The current filter mode, indicating what subset of the list of models should be rendered
 - The “current” model, for situations where our display or edit fragments are visible, to reflect the model that they are showing
 - A 
Throwable, in case there was some exception coming from the repository that we need to show to the user 
As with ToDoModel, ViewState uses AutoValue to create a more-or-less immutable object. So, we have abstract methods for each of those properties that we want to track:
@AutoValue
public abstract class ViewState {
  public abstract boolean isLoaded();
  public abstract List<ToDoModel> items();
  abstract Set<Integer> selections();
  @Nullable public abstract Throwable cause();
  public abstract FilterMode filterMode();
  @Nullable public abstract ToDoModel current();
We also have an associated Builder:
  @AutoValue.Builder
  abstract static class Builder {
    abstract Builder isLoaded(boolean isLoaded);
    abstract Builder items(List<ToDoModel> items);
    abstract Builder selections(Set<Integer> positions);
    abstract Builder cause(Throwable cause);
    abstract Builder filterMode(FilterMode mode);
    abstract Builder current(ToDoModel current);
    abstract ViewState build();
  }
We have a builder() method that returns a Builder with a likely set of default values (e.g., no current selections):
  static Builder builder() {
    return(new AutoValue_ViewState.Builder()
      .isLoaded(false)
      .selections(new HashSet<>())
      .filterMode(FilterMode.ALL));
  }
Beyond that, we have a series of helper methods for common scenarios, such as empty() for returning a Builder set up with no items:
  static Builder empty() {
    return(builder().items(new ArrayList<>()));
  }
…and a toBuilder() method, which creates a Builder pre-populated with the current values from a ViewState, to be able to revise those values and create a fresh ViewState from the Builder:
  private Builder toBuilder() {
    return(builder()
      .isLoaded(isLoaded())
      .cause(cause())
      .items(items())
      .selections(selections())
      .current(current())
      .filterMode(filterMode()));
  }
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.