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
boolean
indicating 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.