我正在使用简单的“房间”表进行设置
@Entity
data class Settings(var user: String = "") {
@PrimaryKey
var id: Long = 1
var activeItem: Int = 0
var developerMode: Boolean = false
var logoUrl: String = ""
var advertisment: String = ""
}
我观察到LiveData表的变化。问题是,如果所有数据都在id = 1的一个条目中,那么当表中的任何值更新时,总是会触发所有观察者。有什么方法可以强制LiveData仅在参数更改时(而不是整个条目)进行观察? 我不想通过其他表来解决它,也不想将其存储在具有不同ID的条目中
以下是来自Dao的查询:
@Query("SELECT activeItem FROM Settings WHERE id = 1")
abstract fun getActiveItem(): LiveData<Int>
@Query("SELECT user FROM Settings WHERE id = 1")
abstract fun getUser(): LiveData<String>
@Query("SELECT developerMode FROM Settings WHERE id = 1")
abstract fun getDeveloperMode(): LiveData<Boolean>
@Query("SELECT logoUrl FROM Settings WHERE id = 1")
abstract fun getLogoUrl(): LiveData<String>
@Query("SELECT advertisment FROM Settings WHERE id = 1")
abstract fun getAdvertisment(): LiveData<String>
答案 0 :(得分:0)
您应使用SharedPreferences
保留用户首选项。您可以通过首选项更改监听器收听首选项更新
preferences.registerOnSharedPreferenceChangeListener { sharedPreferences, key ->
// handle preference update
}
或者您可以实现自己的首选项注册表。
将您的偏好设置模型定义为sealed class
sealed class MyPreference
data class ActiveItemPreference(val number: Int) : MyPreference()
data class UserPreference(val name: String, val age: Int) : MyPreference()
将PreferenceRegistry
作为类型安全的异构容器(有效Java(第3版)。第33条)
object PreferencesRegistry {
private val preferenceLiveDataMap: Map<KClass<*>, MutableLiveData<MyPreference>> =
HashMap<KClass<*>, MutableLiveData<MyPreference>>().apply {
addPreferenceLiveData(ActiveItemPreference::class)
addPreferenceLiveData(UserPreference::class)
/*
Or you if you use kotlin-reflect you can register your preferences like this
Preference::class.sealedSubclasses.forEach { preferenceClass ->
addPreferenceLiveData(preferenceClass)
}
*/
}
operator fun <T : MyPreference> get(preferenceType: KClass<T>): LiveData<T> {
@Suppress("UNCHECKED_CAST") val liveData = preferenceLiveDataMap[preferenceType] as? LiveData<T>
return liveData ?: throw AssertionError("Unexpected preference type $preferenceType")
}
/**
* Store receiver [T] of [toPreferences] extension to receiver [SharedPreferences] of [action]
*/
fun <T : MyPreference> T.toPreferences(context: Context, action: SharedPreferences.(T) -> Unit) {
// get shared preferences to store T
context.getSharedPreferences("preferences", Context.MODE_PRIVATE).action(this)
// send new value of preference T to observers
preferenceLiveDataMap[this::class]?.postValue(this) ?: AssertionError(
"Unable to update preference live data of type ${this::class}")
}
/**
* Helper extension for type safety
*/
private fun <T : MyPreference> MutableMap<KClass<*>, MutableLiveData<MyPreference>>.addPreferenceLiveData(type: KClass<T>) {
put(type, MutableLiveData())
}
}
看看以DSL方式实现的toPreferences
扩展,您可以在《行动中的科特琳》(项目11.2.1)或Type-Safe Builders文章中阅读有关此方法的更多信息。
现在您可以保存属性
UserPreference("Tom", 12).toPreferences(context) { (name, age) ->
// extension for SharedPreferences from Android SDK
edit {
putString("USER_NAME", name)
putInt("USER_AGE", age)
}
}
观察变化
PreferencesRegistry[UserPreference::class].observe(this::getLifecycle) { userPref ->
if (userPref == null)
Log.w("PREFERENCES", "Unexpected nullable user preference")
else
Log.d("PREFERENCES", "User preference updated. New name is ${userPref.name} and new age is ${userPref.age}")
}
加载实施偏好设置并在应用程序启动时调用