Last active
July 19, 2020 13:09
-
-
Save sphrak/f8d86faaf3ca1c99b7d95692e2b1637b to your computer and use it in GitHub Desktop.
MVI Example 2 -- StateModel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainActivity : AppCompatActivity(R.layout.activity_main) { | |
@Inject | |
lateinit var viewModel: MainActivityViewModel | |
private var isInitialised: Boolean = false | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
init() | |
} | |
private fun init() { | |
if (!isInitialised) { | |
lifecycleScope.launch { | |
viewModel | |
.state | |
.collect(::render) | |
} | |
viewModel | |
.send( | |
MainActivityView.Event.OnViewInitialised | |
) | |
isInitialised = true | |
} | |
} | |
private suspend fun render(state: MainActivityView.State): Unit = | |
when (state.renderEvent) { | |
MainActivityView.RenderEvent.Idle -> Unit | |
is MainActivityView.RenderEvent.DisplayText -> | |
renderDisplayText(text = state.renderEvent.text) | |
} | |
private fun renderDisplayText(text: String) { | |
// render text | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object MainActivityView { | |
@ExperimentalCoroutinesApi | |
class StateModel(initialState: State = State()) { | |
private val _state = MutableStateFlow(initialState) | |
val state: StateFlow<State> get() = _state | |
fun setState(newState: State) { | |
_state.value = newState | |
} | |
fun setRenderState(renderEvent: RenderEvent) { | |
_state.value = _state.value.copy(renderEvent = renderEvent) | |
} | |
} | |
data class State( | |
val renderEvent: RenderEvent = RenderEvent.Idle | |
) | |
sealed class Event { | |
object OnViewInitialised : Event() | |
data class OnButtonClicked(val idOfItemClicked: Int) : Event() | |
} | |
sealed class RenderEvent { | |
object Idle : RenderEvent() | |
data class DisplayText(val text: String) : RenderEvent() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainActivityViewModel @Inject constructor( | |
private val state: MainActivityView.StateModel, | |
private val messageOfTheDayRepository: MessageOfTheDayRepository | |
) { | |
val state: StateFlow<MainActivityView.State> | |
get() = stateModel.state | |
fun send(event: MainActivityView.Event): Unit { | |
viewModelScope.launch { | |
reduce(event = event) | |
} | |
} | |
private suspend fun reduce(event: MainActivityView.Event): Unit = | |
when (event) { | |
MainActivityView.Event.OnViewInitialised -> onViewInitialisedEvent() | |
MainActivityView.Event.OnButtonClicked -> onButtonClickedEvent(event.idOfItemClicked) | |
} | |
private suspend fun onViewInitialisedEvent() { | |
val motd: String = withContext(Dispatchers.IO) { | |
messageOfTheDayRepository.getMOTD() | |
} | |
val renderEvent = MainActivityView.RenderEvent.DisplayText(text = motd) | |
stateModel.setRenderEvent(renderEvent = renderEvent) | |
} | |
private fun onButtonClickedEvent(idOfItemClicked: Int) { | |
// do something to handle click | |
println("item clicked: $idOfItemClicked") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment