stateflow一些数据依赖关系的使用
https://www.youtube.com/watch?v=NW03ZAQcTuY
某些数据来自其他数据,可以用flow进行一些变形转换
比较简单一点的例子
private val _users = MutableStateFlow(emptyList<User>())val users = _users.asStateFlow()// private val _loacalUser= MutableStateFlow<User?>(null)
// val localUser = _loacalUser.asStateFlow()val localUser = users.map {users->users.find {it.id =="local"}}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(),null)private fun onUserJoined(user:User){_users.update { it+user }
// if(user.id=="local"){
// _loacalUser.update { user }
// }}private fun onUserInfoUpdate(user: User){_users.update {it.map {curUser->if(curUser.id == user.id) user else curUser //id一样,替换掉,否则还是原来的}}
// if(user.id=="local"){
// _loacalUser.update { user }
// }}
上面,本地用户其实是用户列表中的一个特殊用户,他的ID是local。
如果我们分开存储,像刚开始被注释掉的那些代码,用一个单独的localuser来存储本地用户,当用户列表变化的时候,需要监测是不是local,如果是local,要更新localuser,
当用户信息变化的时候,需要监测下,当前是不是localuser,如果是,则localuser又要更新一下
这样,当方法多了以后,非常麻烦,也容易忘记检查是否是local
于是就取消的localuser的当初存储,而是让他从user list 变化而来
把userlist map 变形,再找到是local的那个用户,然后在statein scope中,以便 引用。
稍微再复杂一点的还给出了一个聊天室的状态
class ChatViewModel : ViewModel() {private val _isLoggedIn = MutableStateFlow(false)private val _chatMessages = MutableStateFlow(emptyList<ChatMessage>())private val _users = MutableStateFlow<List<User>>(emptyList())val chatState = combine(_isLoggedIn,_chatMessages,_users){ isLoggedIn,chatMessages,users->if(isLoggedIn){ChatState(users.map { curUser->ChatPreview(curUser,chatMessages.filter { it.user.id==curUser.id }.maxByOrNull { it.time }?.message)})}else{null}}
}data class ChatState(val chatPreviews: List<ChatPreview>)data class ChatPreview(val user: User,val latestMessage: String?
)data class ChatMessage(val user: User,val message: String, val time: Long
)data class User(val id: String,val name: String,val email: String,val phone: String
)
针对每个个用户的聊天预览列表有多个因素影响,是否登录,用户列表,消息列表
然后根据这三个的数据combine生成一个chatstate的数据
其中 chatpreview中的最新消息,是把所有消息,根据当前用户的过滤后,再找出最近的时间的那条,再取message