我需要更新用户配置文件开关。
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)
)
}
)
}如何观察开关的变化,并在updateUser()中调用ViewModel
我知道这是一种方式,但并不理想。每次初始化网络更新时都会调用它。有没有更好的解决办法?
LaunchedEffect(viewModel.greet) {
viewModel.updateUser()
}发布于 2021-09-18 15:14:22
最好的解决方案是让单向流动和SwitchRow一起使用lambda,就像@Codecameo建议的那样。
但是,如果您想在您的MutableState中观察Viewmodel,您可以使用snapshotFlow作为
var greet: MutableState<Boolean> = mutableStateOf(user.pushSetting.greet)
init {
snapshotFlow { greet.value }
.onEach {
updateUser()
}
.launchIn(viewModelScope)
//...
}从可观察的快照状态创建流。(例如,mutableStateOf归还的州持有者。)snapshotFlow创建一个在收集时运行块并发出结果的流,记录被访问的任何快照状态。当集合继续时,如果应用了一个新的快照来更改按块访问的状态,则流将再次运行块,重新记录被访问的快照状态。如果块的结果与前面的结果不相等,流将发出该新结果。(这种行为类似于Flow.distinctUntilChanged。)除非使用其他流运算符显式取消或限制,否则集合将无限期地继续。
发布于 2021-09-18 05:09:17
在SwitchRow中添加回调lamba,并在任何状态更改时调用它
@Composable
fun SettingCard(viewModel: ProfileViewModel) {
Lists {
Section {
TextRow(text = "手机号码") { }
TextRow(text = "修改密码", line = false) { }
}
Section {
SwitchRow(text = "新好友通知", checkedState = viewModel.greet) {
viewModel.updateUser()
}
SwitchRow(text = "新消息通知", checkedState = viewModel.message) {
viewModel.updateUser()
}
SwitchRow(text = "消息显示详细", line = false, checkedState = viewModel.messageDetails) {
viewModel.updateUser()
}
}
}
}
@Composable
fun SwitchRow(
text: String,
line: Boolean = true,
checkedState: MutableState<Boolean>,
onChange: (Boolean) -> Unit
) {
ListItem(
text = { Text(text) },
trailing = {
Switch(
checked = checkedState.value,
onCheckedChange = {
onChange(it)
checkedState.value = it
},
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colors.primary)
)
}
)
}另一种方法:
您可以将MutableStateFlow<T>保留在视图模型中,并开始在init方法中观察它,并从SwitchRow向其发送一个值,如viewModel.stateFlow.value = value。记住,MutableStateFlow只会在值更改中触发。如果设置相同的值两次,它将丢弃第二个值,并对第一个值执行。
val stateFlow = MutableStateFlow<Boolean?>(null)
init {
stateFlow
.filterNotNull()
.onEach { updateUser() }
.launchIn(viewModelScope)
}在switchRow中
viewmodel.stateFlow.value = !(viewmodel.stateFlow.value?: false)这可能是一个潜在的解决方案。您可以以方便的方式实现它。
https://stackoverflow.com/questions/69230831
复制相似问题