当我将Kotlin与androidx.preference:preference:1.1.1结合使用时,是否需要添加.apply()来写入首选项值?

时间:2020-07-21 08:43:55

标签: android kotlin android-jetpack

代码A的功能是使用#image { display:inline-block; width:30px; height:30px; border:1px solid #000; background-image:url(TOn2E.png); background-repeat:no-repeat; background-position: center; background-size: 150% } 和kotlin来读取和写入首选项值。我不知道这是否正确,你能告诉我吗?

还有,我想我可以像代码B一样使用androidx.preference:preference:1.1.1删除.apply(),对吗?

代码A

androidx.preference:preference:1.1.1

代码B

import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager

class PreferenceTool<T>(private val context: Context, private val name: String, private val default: T) {

    private val prefs: SharedPreferences by lazy {      
        PreferenceManager.getDefaultSharedPreferences(context)
    }

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T = findPreference(name, default)

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        putPreference(name, value)
    }

    @Suppress("UNCHECKED_CAST")
    private fun findPreference(name: String, default: T): T = with(prefs) {
        val res: Any = when (default) {              //I change from Any to Any?
            is Long -> getLong(name, default)
            is String -> getString(name, default)?:default
            is Int -> getInt(name, default)
            is Boolean -> getBoolean(name, default)
            is Float -> getFloat(name, default)
            else -> throw IllegalArgumentException("This type can be saved into Preferences")
        }
        res as T
    }

    @SuppressLint("CommitPrefEdits")
    private fun putPreference(name: String, value: T) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> putString(name, value)
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can't be saved into Preferences")
        }.apply()
    }
}

1 个答案:

答案 0 :(得分:1)

Kotlin标准库中的

with使它的参数可以作为接收器访问。就是这样,仅此而已。它没有Android SharedPreference及其Editor的概念,或者必须提交对其的任何更改。所以这个...

我认为我可以像代码B一样删除.apply() [...],对吗?

...不正确。您可以执行以下操作:

a)最后调用SharedPreference.Editor.apply(),就像您的代码示例A中一样。

b)使用AndroidX Core KTX的SharedPreference.edit {}扩展功能,该扩展功能为您提供了Editor作为接收方,并在最后调用了applycommit

private fun putPreference(name: String, value: T) = prefs.edit(commit = false) {
    when (value) {
        is Long -> putLong(name, value)
        is String -> putString(name, value)
        is Int -> putInt(name, value)
        is Boolean -> putBoolean(name, value)
        is Float -> putFloat(name, value)
        else -> throw IllegalArgumentException("This type can't be saved into Preferences")
    }
}

请参见SharedPreferences.kt - Source

c)重构,创建一个SharedPreference.Editor.put流利风格的扩展函数,然后调用它:

private fun putPreference(name: String, value: T) {
    prefs.edit()
        .put(name, value)
        .apply()
}

private fun SharedPreferences.Editor.put(name: String, value: Any) = apply {
    when (value) {
        is Long -> putLong(name, value)
        is String -> putString(name, value)
        is Int -> putInt(name, value)
        is Boolean -> putBoolean(name, value)
        is Float -> putFloat(name, value)
        else -> throw IllegalArgumentException("This type can't be saved into Preferences")
    }
}

这里,apply也来自Kotlin标准库。我用了它,所以我不必写

                                                                      // vvvvvv this vvvvvv
private fun SharedPreferences.Editor.put(name: String, value: Any): SharedPreferences.Editor {
    when (value) {
        // ...
    }
    return this // <<<<<< and this
}

选择在半年后看到代码时最容易理解的选项。