You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: samples/tutorial/Tutorial4.md
+68-88Lines changed: 68 additions & 88 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,10 +8,6 @@ To follow this tutorial, launch Android Studio and open this folder (`samples/tu
8
8
9
9
Start from the implementation of `tutorial-3-complete` if you're skipping ahead.
10
10
11
-
## Adding new todo items
12
-
13
-
A gap in the usability of the todo app is that it does not let the user create new todo items. We will add an "add" button on the right side of the navigation bar for this.
14
-
15
11
## Refactoring a workflow by splitting it into a parent and child
16
12
17
13
The `TodoListWorkflow` has started to grow and has multiple concerns it's handling — specifically all of the `TodoListScreen` behavior, as well as the actions that can come from the `TodoEditWorkflow`.
@@ -20,7 +16,7 @@ When a single workflow seems to be doing too many things, a common pattern is to
20
16
21
17
### TodoWorkflow
22
18
23
-
Create a new workflow called `Todo` that will be responsible for both the `TodoListWorkflow` and the `TodoEditWorkflow`.
19
+
Create a new workflow called `Todo` that will be responsible for both the `TodoListWorkflow` and the `TodoEditWorkflow`.
#### Moving logic from the TodoList to the TodoWorkflow
29
+
#### Moving logic from the TodoListWorkflow to the TodoWorkflow
34
30
35
31
Move the `ListState` state, input, and outputs from the `TodoListWorkflow` up to the `TodoWorkflow`. It will be owner the list of todo items, and the `TodoListWorkflow` will simply show whatever is passed into its input:
Define the output events from the `TodoListWorkflow` to describe the `new` item action and selecting a todo item, as well as removing the todo list from the `State`:
74
+
Define the output events from the `TodoListWorkflow` to include back and a new `SelectTodo` output. Also, We no longer need to maintain the todo list in the `State` and we can remove it:
79
75
80
76
```kotlin
81
-
object TodoListWorkflow : StatefulWorkflow<ListProps, Unit, Output, TodoListScreen>() {
Because the `State` has no properties anymore, it can't be a data class, so we need to change it to an object. Since the only reason to have a custom type for state is to define the data we want to store, we don't need a custom type anymore so we can just use `Unit`.
116
-
117
110
Change the `WorkflowAction` behaviors to return an output instead of modifying any state:
118
111
119
112
```kotlin
120
-
object TodoListWorkflow : StatefulWorkflow<ListProps, Unit, Output, TodoListScreen>() {
// Tell our parent a new todo item should be created.
136
-
setOutput(NewTodo)
129
+
Move the editing actions from the `TodoListWorkflow` to the `TodoWorkflow`. We won't be able to call these methods until we can respond to output from the `TodoEditWorkflow`, but doing this now helps clean up the `TodoListWorkflow`:
// When a discard action is received, return to the list.
138
+
state = state.copy(step =Step.List)
139
+
}
140
+
141
+
privatefunsaveChanges(
142
+
todo:TodoModel,
143
+
index:Int
144
+
) = action {
145
+
// When changes are saved, update the state of that todo item and return to the list.
146
+
state = state.copy(
147
+
todos = state.todos.toMutableList().also { it[index] = todo },
148
+
step =Step.List
149
+
)
150
+
}
151
+
}
152
+
```
153
+
154
+
Because `TodoWorkflow.State` has no properties anymore, it can't be a `data` class, so we need to change it to an `object`. Since the only reason to have a custom type for state is to define the data we want to store, we don't need a custom type anymore so we can just use `Unit`. You might ask why we need a state at all now. We will discuss that in the next section. For now `Unit` will get us moving forward.
155
+
156
+
```kotlin
157
+
object TodoListWorkflow : StatefulWorkflow<ListProps, Unit, Output, TodoListScreen>() {
// Append a new todo model to the end of the list.
230
-
state = state.copy(
231
-
todos = state.todos +TodoModel(
232
-
title ="New Todo",
233
-
note =""
234
-
)
235
-
)
236
-
}
237
261
}
238
262
```
239
263
240
-
Update the `RootWorkflow` to defer to the `TodoWorkflow` for rendering the `Todo` state. This will get us back into a state where we can build again (albeit without editing support):
264
+
So far `RootWorkflow` is still deferring to the `TodoListWorkflow`. Update the `RootWorkflow` to defer to the `TodoWorkflow` for rendering the `Todo` state. This will get us back into a state where we can build again (albeit without editing support):
// When a discard action is received, return to the list.
302
-
state = state.copy(step =Step.List)
303
-
}
304
-
305
-
privatefunsaveChanges(
306
-
todo:TodoModel,
307
-
index:Int
308
-
) = action {
309
-
// When changes are saved, update the state of that todo item and return to the list.
310
-
state = state.copy(
311
-
todos = state.todos.toMutableList().also { it[index] = todo },
312
-
step =Step.List
313
-
)
314
-
}
315
-
}
316
-
```
297
+
The `TodoWorkflow` now can handle the outputs from the `TodoListWorkflow`. Next, let's add handling for the `TodoEditWorkflow` output events. Earlier we copied `discardChanges` and `saveChanges` into the `TodoWorkflow`. We can now call them.
317
298
318
-
Update the `render` method to show the `TodoEditWorkflow` screen when on the edit step:
299
+
Update the `render` method to show the `TodoEditWorkflow` screen when on the edit step. Handle the `TodoEditWorkflow` output by calling `discardChanges` or `saveChanges`.
0 commit comments