Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using Square Workflow for Android & iOS

Using Square Workflow for Android & iOS

Mohit S

May 18, 2022
Tweet

More Decks by Mohit S

Other Decks in Programming

Transcript

  1. Using Square Workflow for Android & iOS • Purpose •

    Building screens & setting up state • Working with Compose
  2. Layout Runner override fun showRendering(rendering: LoginScreen) { loginViewBinding.username.text = rendering.username

    loginViewBinding.username.setTextChangedListener { rendering.onUsernameChanged(it.toString()) } loginViewBinding.login.setOnClickListener { rendering.onLoginClicked() } }
  3. Layout Runner override fun showRendering(rendering: LoginScreen) { loginViewBinding.username.text = rendering.username

    loginViewBinding.username.setTextChangedListener { rendering.onUsernameChanged(it.toString()) } loginViewBinding.login.setOnClickListener { rendering.onLoginClicked() } }
  4. Layout Runner override fun showRendering(rendering: LoginScreen) { loginViewBinding.username.text = rendering.username

    loginViewBinding.username.setTextChangedListener { rendering.onUsernameChanged(it.toString()) } loginViewBinding.login.setOnClickListener { rendering.onLoginClicked() } }
  5. Layout Runner override fun showRendering(rendering: LoginScreen) { loginViewBinding.username.text = rendering.username

    loginViewBinding.username.setTextChangedListener { rendering.onUsernameChanged(it.toString()) } loginViewBinding.login.setOnClickListener { rendering.onLoginClicked() } }
  6. fun render(renderState: State): LoginScreen { LoginScreen( username = renderState.username, onUsernameChanged

    = { context.actionSink.send(onUserChanged(it)) }, onLoginCliked = {} ) } Workflow
  7. View Model class LoginViewModel : ViewModel() { val renderings: StateFlow<LoginScreen>

    by lazy { renderWorkflowIn( workflow = LoginWorkflow, scope = viewModelScope, savedStateHandle = savedState ) } }
  8. View Model class LoginViewModel : ViewModel() { val renderings: StateFlow<LoginScreen>

    by lazy { renderWorkflowIn( workflow = LoginWorkflow, scope = viewModelScope, savedStateHandle = savedState ) } }
  9. View class LoginActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) 
 
 val model: LoginViewModel by viewModels() setContentView( WorkflowLayout(this).apply { start(model.renderings) } ) } }
  10. View class LoginActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) 
 
 val model: LoginViewModel by viewModels() setContentView( WorkflowLayout(this).apply { start(model.renderings) } ) } }
  11. View class LoginActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) 
 setContentView( WorkflowLayout(this).apply { start(model.renderings) } ) } }
  12. sealed class State { object Login : State() data class

    Todo(val username: String) : State() } State
  13. Root Workflow object RootWorkflow : StatefulWorkflow { fun render( renderProps:

    Unit, renderState: State, context: RenderContext ): BackStackScreen<Any> }
  14. Root Workflow fun render( ... ): BackStackScreen<Any> { 
 val

    backstackScreens = mutableListOf<Any>() }
  15. Root Workflow fun render( ... ): BackStackScreen<Any> { 
 val

    loginScreen = context.renderChild(LoginWorkflow) }
  16. Root Workflow fun render( ... ): BackStackScreen<Any> { 
 val

    loginScreen = context.renderChild(LoginWorkflow) backstackScreens += loginScreen }
  17. Root Workflow fun render( ... ): BackStackScreen<Any> { 
 when

    (renderState) { is Todo -> { val todoScreen = context.renderChild(TodoWorkflow) backstackScreens += todoScreen } } }
  18. Root Workflow fun render( ... ): BackStackScreen<Any> { when (renderState)

    { is Todo -> { val todoScreen = context.renderChild(TodoWorkflow) backstackScreens += todoScreen } } }
  19. Root Workflow fun render( ... ): BackStackScreen<Any> { when (renderState)

    { is Todo -> { val todoScreen = context.renderChild( TodoWorkflow, ListProps(username = renderState.username) ) } } }
  20. View Model class LoginViewModel : ViewModel() { val renderings: StateFlow<LoginScreen>

    by lazy { renderWorkflowIn( workflow = LoginWorkflow, scope = viewModelScope, savedStateHandle = savedState ) } }
  21. View Model class LoginViewModel : ViewModel() { val renderings: StateFlow<LoginScreen>

    by lazy { renderWorkflowIn( workflow = RootWorkflow, scope = viewModelScope, savedStateHandle = savedState ) } }
  22. Binding composeScreenViewFactory<HelloWorkflow.Rendering> { rendering, _ -> Text( rendering.message, modifier =

    Modifier .clickable(onClick = rendering.onClick) .fillMaxSize() .wrapContentSize(Alignment.Center) ) }
  23. Binding composeScreenViewFactory<HelloWorkflow.Rendering> { rendering, _ -> Text( rendering.message, modifier =

    Modifier .clickable(onClick = rendering.onClick) .fillMaxSize() .wrapContentSize(Alignment.Center) ) }
  24. State enum class State { Hello, Goodbye; fun theOtherState(): State

    = when (this) { Hello -> Goodbye Goodbye -> Hello } }
  25. Workflow object HelloWorkflow : StatefulWorkflow { 
 override fun render():

    Rendering = Rendering( message = renderState.name, onClick = { context.actionSink.send(helloAction) } ) 
 }