CV工程师
2024-09-30 04:33:16 阅读:184
以下是使用 Jetpack Compose、Room 和 ViewModel 实现设置信息持久化并自动更新 UI 的步骤:
一、创建 Room 数据库相关部分
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "settings")
data class SettingEntity(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val settingName: String,
val settingValue: String
)
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
@Dao
interface SettingDao {
@Insert
suspend fun insertSetting(setting: SettingEntity)
@Query("SELECT * FROM settings WHERE settingName = :name")
suspend fun getSettingByName(name: String): SettingEntity?
}
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [SettingEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun settingDao(): SettingDao
}
二、创建 ViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class SettingsViewModel : ViewModel() {
private val _appName = MutableStateFlow<String?>(null)
val appName: StateFlow<String?> = _appName
private val _dayNightMode = MutableStateFlow<String?>(null)
val dayNightMode: StateFlow<String?> = _dayNightMode
fun loadAppNameFromDatabase(db: AppDatabase) {
viewModelScope.launch {
val setting = db.settingDao().getSettingByName("softwareName")
_appName.value = setting?.settingValue
}
}
fun saveAppNameToDatabase(db: AppDatabase, appName: String) {
viewModelScope.launch {
val existingSetting = db.settingDao().getSettingByName("softwareName")
if (existingSetting == null) {
db.settingDao().insertSetting(SettingEntity(settingName = "softwareName", settingValue = appName))
} else {
existingSetting.settingValue = appName
db.settingDao().insertSetting(existingSetting)
}
_appName.value = appName
}
}
fun loadDayNightModeFromDatabase(db: AppDatabase) {
viewModelScope.launch {
val setting = db.settingDao().getSettingByName("softwareDayNigh")
_dayNightMode.value = setting?.settingValue
}
}
fun saveDayNightModeToDatabase(db: AppDatabase, mode: String) {
viewModelScope.launch {
val existingSetting = db.settingDao().getSettingByName("softwareDayNigh")
if (existingSetting == null) {
db.settingDao().insertSetting(SettingEntity(settingName = "softwareDayNigh", settingValue = mode))
} else {
existingSetting.settingValue = mode
db.settingDao().insertSetting(existingSetting)
}
_dayNightMode.value = mode
}
}
}
三、在 Jetpack Compose 中使用
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@Composable
fun SoftwareNameSettingsPage() {
val db = rememberDatabase()
val viewModel = remember { SettingsViewModel() }
var appName by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
viewModel.loadAppNameFromDatabase(db)
}
LaunchedEffect(viewModel.appName) {
viewModel.appName.value?.let {
appName = it
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
TextField(
value = appName,
onValueChange = {
appName = it
},
label = { Text("软件名称") },
modifier = Modifier.fillMaxWidth()
)
Button(
onClick = {
launch {
viewModel.saveAppNameToDatabase(db, appName)
}
},
modifier = Modifier.padding(top = 16.dp)
) {
Text("保存")
}
}
}
private fun rememberDatabase(): AppDatabase {
return androidx.room.Room.databaseBuilder(
LocalContext.current,
AppDatabase::class.java,
"app_database"
).build()
}
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@Composable
fun DayNightModeSettingsPage() {
val db = rememberDatabase()
val viewModel = remember { SettingsViewModel() }
var selectedMode by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
viewModel.loadDayNightModeFromDatabase(db)
}
LaunchedEffect(viewModel.dayNightMode) {
viewModel.dayNightMode.value?.let {
selectedMode = it
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text("选择白天黑夜模式:")
RadioButton(
selected = selectedMode == "light",
onClick = { selectedMode = "light" },
modifier = Modifier.padding(top = 8.dp)
) {
Text("白天模式")
}
RadioButton(
selected = selectedMode == "dark",
onClick = { selectedMode = "dark" },
modifier = Modifier.padding(top = 8.dp)
) {
Text("黑夜模式")
}
Button(
onClick = {
launch {
viewModel.saveDayNightModeToDatabase(db, selectedMode)
}
},
modifier = Modifier.padding(top = 16.dp)
) {
Text("保存")
}
}
}
private fun rememberDatabase(): AppDatabase {
return androidx.room.Room.databaseBuilder(
LocalContext.current,
AppDatabase::class.java,
"app_database"
).build()
}
这样,在不同的页面可以分别配置软件名称和白天黑夜模式,并且数据库的更改会自动反映到 UI 上。
评论
扫描二维码获取文章详情
更多精彩内容尽在:WWW.ZNGG.NET