当通过将同步状态设置为 true 开始同步文件时,我试图显示一个循环进度指示器。 当同步结束时,变量变为 false。
这是我的 MainViewModel 的代码。
public val syncing = MutableStateFlow(false)
fun syncFiles(context: Context) {
if ((getApplication<MainApplication>()).dropboxClient?.isClientReady() != true) {
showShortToast(context, "Dropbox is not connected")
return;
}
viewModelScope.launch {
syncing.update {true}
val result = withContext(Dispatchers.IO) {
var result = false;
try {
getApplication<MainApplication>().initlializeDropboxFromLocalCreds()
updateMyData()
saveFiles()
Timber.d(bookRepo.getAllBooks().joinToString(", "))
result = true;
} catch (it: Exception) {
Timber.tag("Error").e(it.toString())
result = false
}
syncing.update {false}
result;
}
if (result) {
showShortToast(context, "Books synced properly")
} else {
showShortToast(context, "Couldn't sync books")
}
}
}
但是可组合项内部的状态不会改变。
我已经调试了该问题,并且可组合项仅在应用程序启动时构造一次。
fun MainPage(
innerPadding: PaddingValues,
modifier: Modifier = Modifier,
navigateToReader: (filePath: String) -> Unit,
mainViewModel: MainViewModel = viewModel()
) {
Box {
val state by mainViewModel.syncing.collectAsState()
if (state) {
CircularProgressIndicator(
// progress = { currentProgress },
modifier = Modifier.fillMaxWidth(),
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.surfaceVariant,
)
} else {
Column(
modifier = Modifier
.padding(innerPadding)
.padding(horizontal = 15.dp, vertical = 20.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Greeting(navigateToReader = navigateToReader)
}
}
}
}
我尝试过
mutableStateOf
、remember
与 mutableStateOf
结合使用,但没有任何效果。
请解释为什么会发生这种情况。
我已尝试调试该问题,但可组合仅组合一次。
我希望状态在同步开始时更改为 true,在同步结束时更改为 false(这正在发生)。 UI 应相应更新以显示循环进度指示器(这并未发生)。
a) ViewModel 中的主要变化:
使用私有 MutableStateFlow (_syncing) 和公共 StateFlow (syncing) 以获得更好的封装。
使用 _syncing.value = true 和 _syncing.value = false 更新状态。
class MainViewModel : ViewModel() {
private val _syncing = MutableStateFlow(false)
val syncing: StateFlow<Boolean> = _syncing
fun syncFiles(context: Context) {
if ((getApplication<MainApplication>()).dropboxClient?.isClientReady() != true) {
showShortToast(context, "Dropbox is not connected")
return
}
viewModelScope.launch {
_syncing.value = true
val result = withContext(Dispatchers.IO) {
var result = false
try {
getApplication<MainApplication>().initlializeDropboxFromLocalCreds()
updateMyData()
saveFiles()
Timber.d(bookRepo.getAllBooks().joinToString(", "))
result = true
} catch (it: Exception) {
Timber.tag("Error").e(it.toString())
result = false
}
result
}
_syncing.value = false
if (result) {
showShortToast(context, "Books synced properly")
} else {
showShortToast(context, "Couldn't sync books")
}
}
}
}
b) 可组合项的主要变化:
通过 mainViewModel.syncing.collectAsState() 使用 val state 观察状态。
确保 Box 使用modifier = modifier.fillMaxSize() 以获得正确的布局。
fun MainPage(
innerPadding: PaddingValues,
modifier: Modifier = Modifier,
navigateToReader: (filePath: String) -> Unit,
mainViewModel: MainViewModel = viewModel()) {
val state by mainViewModel.syncing.collectAsState()
Box(modifier = modifier.fillMaxSize()) {
if (state) {
CircularProgressIndicator(
modifier = Modifier.fillMaxWidth(),
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.surfaceVariant,
)
} else {
Column(
modifier = Modifier
.padding(innerPadding)
.padding(horizontal = 15.dp, vertical = 20.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Greeting(navigateToReader = navigateToReader)
}
}
}
}
通过进行这些更改,您的可组合项应该正确观察同步状态并在状态更改时重新组合,在同步时显示 CircularProgressIndicator,在不同步时显示 Column。