Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 53 additions & 6 deletions samples/tutorial/Tutorial1.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,63 @@ Start by creating a new workflow and screen by creating a new file with the [fil
![New Workflow](images/new-workflow.png)
![Workflow Name](images/workflow-name.png)

Follow the same steps using the `Layout Runner (ViewBinding)` template.
The template does not create everything needed. Manually add objects for `State` and `Output`. We'll define `WelcomeScreen` in a moment:

```kotlin
object WelcomeWorkflow : StatefulWorkflow<Unit, State, Output, WelcomeScreen>() {

object State
object Output

override fun initialState(
props: Unit,
snapshot: Snapshot?
): State = TODO("Initialize state")

override fun render(
props: Unit,
state: State,
context: RenderContext
): WelcomeScreen {
TODO("Render")
}

override fun snapshotState(state: State): Snapshot? = Snapshot.write {
TODO("Save state")
}
}
```

Use the `Layout Runner (ViewBinding)` template to create a second file.

![Layout Runner Name](images/layout-runner-name.png)

```kotlin
@OptIn(WorkflowUiExperimentalApi::class)
class WelcomeLayoutRunner(
private val binding: WelcomeViewBinding
) : LayoutRunner<WelcomeScreen> {

override fun showRendering(
rendering: WelcomeScreen,
viewEnvironment: ViewEnvironment
) {
TODO("Update ViewBinding from rendering")
}

companion object : ViewFactory<WelcomeScreen> by bind(
WelcomeViewBinding::inflate, ::WelcomeLayoutRunner
)
}
```

### Screens, View Factories, and Layout Runners

Let's start with what a "screen" is, and how it relates to views.

"Screen" is just the term we use to refer to a value type that represents the view model for a logical screen. Sometimes we'll even use the terms "screen" and "view model" interchangeably. It has no special type. Typically, a screen will be used as the rendering type for the workflow that is responsible for that screen. A screen is usually a data class, since that's the easiest way to make value type-like classes in Kotlin.

For our welcome screen, we'll define what it needs for a backing view model:
For our welcome screen, we'll create a new class and define what it needs for a backing view model:
```kotlin
data class WelcomeScreen(
/** The current name that has been entered. */
Expand All @@ -43,7 +91,8 @@ data class WelcomeScreen(
)
```

Then we need to create a `ViewFactory` that knows how to create an Android `View` to draw the actual screen. The easiest way to create a `ViewFactory` is to create a layout runner. A layout runner is a class that has a reference to the view and knows how to update the view given an instance of a screen. In a typical app, every screen will have a layout runner. Layout runners can also work with AndroidX `ViewBinding`s, which we'll use to define the `WelcomeLayoutRunner`. We have a pre-built `WelcomeViewBinding` that you can use. This binding will be autogenerated from layout files in `tutorials-views` when you first build the app. However if you would like to create and lay out the view yourself instead, feel free to do so!
Then we need to create a `ViewFactory` that knows how to create an Android `View` to draw the actual screen. The easiest way to create a `ViewFactory` is to create a layout runner. A layout runner is a class that has a reference to the view and knows how to update the view given an instance of a screen. In a typical app, every screen will have a layout runner. Layout runners can also work with AndroidX `ViewBinding`s, which we'll use to define the `WelcomeLayoutRunner`. We have a pre-built `WelcomeViewBinding` that you can use. This binding will be autogenerated from layout files in `tutorials-views` when you first build the app. If Android Studio does not automatically find the file, you can manually import it `import workflow.tutorial.views.databinding.WelcomeViewBinding
`. However if you would like to create and lay out the view yourself instead, feel free to do so!

```kotlin
class WelcomeLayoutRunner(
Expand Down Expand Up @@ -87,8 +136,6 @@ object WelcomeWorkflow : StatefulWorkflow<Unit, State, Output, WelcomeScreen>()

// …

object Output

override fun render(
renderProps: Unit,
renderState: State,
Expand Down Expand Up @@ -141,7 +188,7 @@ Right now, the workflow isn't handling any of the events from the UI. Let's upda

All workflows have a `State` type that represents the internal state of the workflow. This should be all of the data for which *this* workflow is _responsible_. It usually corresponds to the state for the UI.

Let's model the first part of state that we want to track: the login `username`. Update the `State` type to include a username property. We will also need to update `initialState` to give an initial value:
Let's model the first part of state that we want to track: the login `username`. Update the `State` to a `data class` and include a username property. We will also need to update `initialState` to give an initial value:

```kotlin
object WelcomeWorkflow : StatefulWorkflow<Unit, State, Output, WelcomeScreen>() {
Expand Down
2 changes: 1 addition & 1 deletion samples/tutorial/Tutorial2.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ Workflows can only communicate with each other through their "properties" as inp

Our welcome workflow has a login button that doesn't do anything, and we'll now handle it and let our parent know that we've "logged in" so it can navigate to another screen.

Add an action for `onLogin` and define our `OutputT` type as a new `data class LoggedIn` to be able to message our parent:
Add an action for `onLogin` and change our `OutputT` type from `Output` to a new `data class LoggedIn` to be able to message our parent:

```kotlin

Expand Down
Binary file added samples/tutorial/images/layout-runner-name.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/tutorial/images/workflow-name.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.