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.