MVI的模板代码分享
文章目录
-
-
- 各种模式对比
- mvi 的模板代码
-
各种模式对比
从 mvc 到 mvp,mvvm 再到 mvi,目的是让代码结构更清晰,更容易维护。
模式 | 优点 | 缺点 |
---|---|---|
mvc | 简单,快速 ,适合小项目 | controller会越来越臃肿,view和model耦合 |
mvp | view只依赖于presenter层,解耦view和model | presenter通过接口回调给view,接口会越来越多,有内存泄漏风险 |
mvvm | viewModel和view数据双向绑定,不需要过多接口,隐藏回调细节,减少内存泄漏风险 | 实现起来复杂 |
mvi | 将数据封装成userIntent和uistate,实现数据单向流动,结构更加简单 | 实现起来复杂,userIntent和uistate容易膨胀 |
其中这篇文章有非常详细的介绍:
https://blog.csdn.net/lengjiye/article/details/129736951
mvi 的模板代码
userIntent
将 view 的一些操作封装各种 Intent
interface IUserIntent {
}
例如,以下是登录界面的各种意图
sealed class LoginUserIntent : IUserIntent {data class PhoneNumLogin(val phone: String) : LoginUserIntent()data class facebookLogin(val accountNum: String) : LoginUserIntent()data class WechatLogin(val wechatAccount: String) : LoginUserIntent()}
uistate
我们在进行一些逻辑运算之后,会获取到各种数据,然后将这些数据封装成 uistate
interface IUiState {
}
例如,登录界面的各种状态
sealed class LoginUiState : IUiState {data class LoginSuccessState(val type: String, val userId: String?) : LoginUiState()data class LoginFailedState(val type: String,val errCode: Int, val msg: String?) : LoginUiState()}
模板
abstract class BaseViewModel<I: IUserIntent,S: IUiState> : ViewModel() {private val _userIntentFlow: MutableStateFlow<I> = MutableStateFlow(mNoneValueIntent)protected val mUiState: MutableLiveData<S> = MutableLiveData()abstract val mNoneValueIntent: Iinit {/*** 处理用户意图*/_userIntentFlow.onEach { userIntent ->println("userIntentFlow onEach:$userIntent")userIntent?.let { handleIntent(it) }}.launchIn(viewModelScope)}abstract fun handleIntent(userIntent: I)/*** 驱动UI更新*/fun obtainUiState(): MutableLiveData<S> {return mUiState}/*** 延迟10ms重置状态,防止连续发送相同状态stateFlow没处理*/suspend fun sendUserIntent(userIntent: I) {_userIntentFlow.tryEmit(userIntent)delay(10)_userIntentFlow.tryEmit(mNoneValueIntent)}
}