我正在努力在 Android Jetpack Compose 中实现 DataStore 首选项库,以便在我的应用程序中保留一些用户设置。每当我尝试从 Composable 组件访问 SettingsViewModel 时,应用程序就会崩溃并且我收到以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.boldmethod, PID: 5415
java.lang.RuntimeException: Cannot create an instance of class com.boldmethod.Models.SettingsViewModel
...
Caused by: java.lang.InstantiationException: java.lang.Class<com.packageName.Models.SettingsViewModel> has no zero argument constructor
我正在按照文档创建 DataStore 和视图模型,所以也许我在 Composable 中没有正确使用它们。这是相关的源代码:
摇篮
dependencies {
// Kotlin/Core
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.20"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
// Compose
implementation "androidx.compose.ui:ui:1.0.0-alpha08"
implementation "androidx.compose.material:material:1.0.0-alpha08"
implementation "androidx.compose.runtime:runtime:1.0.0-alpha08"
implementation "androidx.compose.runtime:runtime-livedata:1.0.0-alpha08"
implementation "androidx.compose.runtime:runtime-rxjava2:1.0.0-alpha08"
// Navigation
def nav_compose_version = "1.0.0-alpha03"
implementation "androidx.navigation:navigation-compose:$nav_compose_version"
// Architecture
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha05"
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
//implementation "android.arch.lifecycle:runtime:2.1.0"
// UI/Material
implementation 'com.google.android.material:material:1.2.1'
implementation "androidx.ui:ui-tooling:1.0.0-alpha07"
// Testing
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
创建 DataStore 的用户首选项存储库
class UserPreferencesRepository private constructor(context: Context) {
data class UserPreferences(
val resolution: String,
val theme: String,
)
private val dataStore: DataStore<Preferences> =
context.createDataStore(name = "userPreferences")
private object PreferencesKeys {
val RESOLUTION = preferencesKey<String>("resolution")
val THEME = preferencesKey<String>("theme")
}
// Read from the DataStore with a Flow object.
val userPreferencesFlow: Flow<UserPreferences> = dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}.map { preferences ->
// Get values or a default value.
val resolution = preferences[PreferencesKeys.RESOLUTION] ?: "HD"
val theme = preferences[PreferencesKeys.THEME] ?: "Auto"
UserPreferences(resolution, theme)
}
// Edit the DataStore.
suspend fun updateResolution(resolution: String) {
dataStore.edit { preferences ->
// when statement here to change more than just res.
preferences[PreferencesKeys.RESOLUTION] = resolution
}
}
}
设置视图模型
class SettingsViewModel(
userPreferencesRepository: UserPreferencesRepository
) : ViewModel() {
private val _resolution = MutableLiveData("HD")
val resolution: LiveData<String> = _resolution
fun onResolutionChanged(newResolution: String) {
when (newResolution) {
"540p" -> _resolution.value = "720p"
"720p" -> _resolution.value = "HD"
"HD" -> _resolution.value = "540p"
}
}
}
设置组件
@Composable
fun Settings(
settingsViewModel: SettingsViewModel = viewModel(),
) {
val resolution: String by settingsViewModel.resolution.observeAsState("")
ScrollableColumn(Modifier.fillMaxSize()) {
Column {
...
Card() {
Row() {
Text(
text = "Resolution",
)
Text(text = resolution,
modifier = Modifier.clickable(
onClick = { settingsViewModel.onResolutionChanged(resolution) },
indication = null))
}
}
...
}
}
}
试图让它与 Compose 一起工作对我来说是一场斗争,我希望得到任何帮助。非常感谢!