我想提供此问题的上下文。我见过独特的解决方案,人们可以创建从SharedPreferences而不是后备字段读取/写入的委托。为此,例如:
class SharedPrefsString(private val sharedPrefs: SharedPreferences) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return sharedPrefs.getString(property.name, "")
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
sharedPrefs.edit().putString(property.name, value).apply()
}
}
var myString: String by SharedPrefsString(myPrefs)
但是,我希望我可以对通用枚举做同样的事情,因为所有枚举都有一个valueOf(string)
方法,但是下面的方法不起作用。我在评论中放了一些我尝试过的东西:
class SharedPrefsEnum<T : Enum<T>>(private val sharedPrefs: SharedPreferences) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
// Doesn't work, can't reference T, which makes sense.
// return T.valueOf(sharedPrefs.getString(property.name, ""))
// Can't use reified type here, which makes sense.
// return enumValueOf<T>(sharedPrefs.getString(property.name, ""))
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
sharedPrefs.edit().putString(property.name, value.name).apply()
}
}
var myEnum: MyEnum by SharedPrefsEnum(myPrefs)
像这样可能吗?
答案 0 :(得分:6)
以您的答案为基础,可以避免使用enumConstants
属性的反射:
class SharedPrefsEnum<T : Enum<T>>(
private val sharedPrefs: SharedPreferences,
private val clazz: Class<T>
) : ReadWriteProperty<Any, T> {
operator fun getValue(thisRef: Any, property: KProperty<*>): T {
val enumName = sharedPrefs.getString(property.name, "")
return clazz.enumConstants.find { it.name == enumName }!!
}
operator fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
sharedPrefs.edit().putString(property.name, value.name).apply()
}
}
然后,您可以使用以下方法轻松添加代表:
inline fun <reified T : Enum<T>> sharedPreferences(prefs: SharedPreferences) =
SharedPrefsEnum(prefs, T::class.java)
允许您为其分配:
private var myEnum: MyEnum by sharedPreferences(preferences)
您可能希望使属性类型可为空,就像您的SharedPreferences
不包含该值一样,这将在访问该值时引发异常。
答案 1 :(得分:2)
我能够使用反射解决此问题。感谢佐伊为我指明了正确的方向。
我也必须为枚举传递类,但是使用它我可以使用反射找到valueOf
并使用从首选项中获得的字符串进行调用。
class SharedPrefsEnum<T : Enum<T>>(private val sharedPrefs: SharedPreferences, private val clazz: Class<T>) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
val prefsString = sharedPrefs.getString(property.name, "")
val method = clazz.getDeclaredMethod("valueOf", String::class.java)
return method.invoke(null, prefsString) as T
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
sharedPrefs.edit().putString(property.name, value.name).apply()
}
}
答案 2 :(得分:1)
我正在使用这个
Right
这是实现:
var lastUpdate by PersistedProperty("lastUpdate",0L)