I have a need to update the user profile switch
class ProfileViewModel : BaseViewModel() {
var greet = mutableStateOf(user.pushSetting.greet)
var message = mutableStateOf(user.pushSetting.message)
var messageDetails = mutableStateOf(user.pushSetting.messageDetails)
var follow = mutableStateOf(user.pushSetting)
var like = mutableStateOf(user.pushSetting.like)
var comment = mutableStateOf(user.pushSetting.comment)
fun updateUser() {
println("--")
}
}
2.Composable
@Composable
fun SettingCard(viewModel: ProfileViewModel) {
Lists {
Section {
TextRow(text = "手机号码") { }
TextRow(text = "修改密码", line = false) { }
}
Section {
SwitchRow(text = "新好友通知", checkedState = viewModel.greet)
SwitchRow(text = "新消息通知", checkedState = viewModel.message)
SwitchRow(text = "消息显示详细", line = false, checkedState = viewModel.messageDetails)
}
}
}
3.SwitchRow
@Composable
fun SwitchRow(text: String, line: Boolean = true, checkedState: MutableState<Boolean>) {
ListItem(
text = { Text(text) },
trailing = {
Switch(
checked = checkedState.value,
onCheckedChange = { checkedState.value = it },
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colors.primary)
)
}
)
}
How can I observe the change of the switch and call updateUser() in ViewModel
I know this is a way, but it is not ideal. The network update will be called every time it is initialized. Is there a better solution?
LaunchedEffect(viewModel.greet) {
viewModel.updateUser()
}
The best solution for this would be to have unidirectional flow with SwitchRow
with a lambda as @Codecameo advised.
But if you want to observe a MutableState inside your Viewmodel
you can use snapshotFlow
s as
var greet: MutableState<Boolean> = mutableStateOf(user.pushSetting.greet)
init {
snapshotFlow { greet.value }
.onEach {
updateUser()
}
.launchIn(viewModelScope)
//...
}
Create a Flow from observable Snapshot state. (e.g. state holders returned by mutableStateOf.) snapshotFlow creates a Flow that runs block when collected and emits the result, recording any snapshot state that was accessed. While collection continues, if a new Snapshot is applied that changes state accessed by block, the flow will run block again, re-recording the snapshot state that was accessed. If the result of block is not equal to the previous result, the flow will emit that new result. (This behavior is similar to that of Flow.distinctUntilChanged.) Collection will continue indefinitely unless it is explicitly cancelled or limited by the use of other Flow operators.