我有以下处理数据存储首选项的代码,我想知道如何使用视图模型实现它,然后在可组合视图中访问数据。另外,我想知道如何在视图模型中处理改进的 HTTP 请求,因为根据我的理解,最佳实践是将数据突变和数据处理保留在 UI 组件之外。我假设我需要两种数据模型,一种用于首选项,一种用于 HTTP 请求数据。任何帮助将不胜感激。谢谢你。
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
val ACCOUNT_TYPE = stringPreferencesKey("account_type")
val accountTypeFlow: Flow<String> = applicationContext.dataStore.data
.map { preferences ->
preferences[ACCOUNT_TYPE] ?: ""
}
编辑:更清楚地说,我有代码来设置和获取 DataStore 首选项数据,但我不知道如何在视图模型中实现它,并在可组合视图中从视图模型访问数据。我还想为从 Retrofit HTTP 请求接收到的数据创建一个视图模型,但我也不确定如何做到这一点。
编辑 2:我可以提出一个有关 Retrofit 的单独问题,但我可以将第一个问题缩小为:如何在视图模型中实现 DataStore 变量的获取和设置功能?
DataStore
中使用 ViewModel
首选项,您需要创建一个 ViewModel
来获取和更新首选项,有点像 Ethan Denvir 中的“Android Compose DataStore 教程 ”。
class PreferencesViewModel(application: Application) : AndroidViewModel(application) {
private val dataStore: DataStore<Preferences> = application.dataStore
// LiveData to expose the account type from DataStore
private val _accountType = MutableLiveData<String>()
val accountType: LiveData<String> = _accountType
init {
viewModelScope.launch {
fetchAccountType()
}
}
private suspend fun fetchAccountType() {
dataStore.data.map { preferences ->
preferences[ACCOUNT_TYPE] ?: ""
}.collect { accountTypeValue ->
_accountType.postValue(accountTypeValue)
}
}
// Function to update account type in DataStore
fun updateAccountType(newAccountType: String) {
viewModelScope.launch {
dataStore.edit { preferences ->
preferences[ACCOUNT_TYPE] = newAccountType
}
}
}
}
要访问
可组合函数中的
PreferencesViewModel
,您可以使用viewModel()
可组合函数(如此示例中所示)来获取ViewModel
的实例,并使用observeAsState()
来观察LiveData的状态在您的可组合项中。
@Composable
fun PreferencesScreen(preferencesViewModel: PreferencesViewModel = viewModel()) {
val accountType by preferencesViewModel.accountType.observeAsState("")
Column {
Text(text = "Account Type: $accountType")
Button(onClick = {
preferencesViewModel.updateAccountType("NewAccountType")
}) {
Text("Update Account Type")
}
}
}
为了处理 Retrofit HTTP 请求,可以使用类似的
ViewModel
方法,其中 ViewModel
将处理网络请求并相应地更新 UI 状态。