Обернуть геттеры и сеттеры в классе SharedPreferences - PullRequest
0 голосов
/ 12 июня 2018

Я хочу повторно использовать код и перенос геттеров и сеттеров, потому что они имеют одинаковую функциональность.

Я полагаю, что для каждого типа есть общая функция.

Я считаю,лучше поддерживать определенные свойства, а не делать все общие, поскольку код более понятен для доступа к этим свойствам.Например: MyPrefs.instance.prefOne

Класс SharedPreferences с двумя «идентичными» функциями:

import android.content.Context
import android.content.SharedPreferences

class MyPrefs private constructor() {

    companion object {
        private const val PREF_ONE = "prefOne"
        private const val PREF_TWO = "prefTwo"

        val instance = MyPrefs()
    }

    private lateinit var prefs: SharedPreferences

    fun init(context: Context) {
        this.prefs = context.getSharedPreferences(context.applicationContext.packageName
                + "." + MyPrefs::class.java.simpleName, Context.MODE_PRIVATE)
    }

    fun clear() {
        prefs.edit().clear().apply()
    }

    var prefOne: String
        get() = prefs.getString(PREF_ONE, "")
        set(prefOne) = prefs.edit().putString(PREF_ONE, prefOne).apply()

    var prefTwo: String
        get() = prefs.getString(PREF_TWO, "")
        set(prefTwo) = prefs.edit().putString(PREF_TWO, prefTwo).apply()
}

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Я нашел элегантное решение благодаря ответу zsmb13.

import android.content.SharedPreferences
import kotlin.reflect.KProperty

class DelegatedPreferences<T>(val prefs: SharedPreferences, private val defaultValue: T) {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return getPreference(property.name, defaultValue)
    }

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

    private fun getPreference(key: String, defaultValue: T): T {
        with(prefs) {
            val result: Any = when (defaultValue) {
                is Boolean -> getBoolean(key, defaultValue)
                is Int -> getInt(key, defaultValue)
                is Long -> getLong(key, defaultValue)
                is Float -> getFloat(key, defaultValue)
                is String -> getString(key, defaultValue)
                else -> throw IllegalArgumentException()
            }
            @Suppress("UNCHECKED_CAST")
            return result as T
        }
    }

    private fun setPreference(key: String, value: T) {
        with(prefs.edit()) {
            when (value) {
                is Boolean -> putBoolean(key, value)
                is Int -> putInt(key, value)
                is Long -> putLong(key, value)
                is Float -> putFloat(key, value)
                is String -> putString(key, value)
                else -> throw IllegalArgumentException()
            }.apply()
        }
    }
}

Конкретный класс предпочтений теперь очень прост и чист:

import android.content.Context
import android.content.SharedPreferences

class MyPrefs private constructor() {

    companion object {
        val instance = MyPrefs()
    }

    val prefs: SharedPreferences by lazy {
        val context = App.instance
        context.getSharedPreferences(context.packageName + "." + MyPrefs::class.java.simpleName, Context.MODE_PRIVATE)
    }

    fun clear() {
        prefs.edit().clear().apply()
    }

    var anyProperty: String by DelegatedPreferences(prefs, "")
}

И вызов очень прост:

MyPrefs.instance.anyProperty = "Hello!"
Log.d("***", MyPrefs.instance.anyProperty) // Hello!
0 голосов
/ 12 июня 2018

Вы можете решить эту проблему с помощью делегированных свойств .

Вот очень простой пример реализации для хранения только String предпочтений:

class PreferencesDelegate(val context: Context, val key: String, val defaultValue: String = "") {
    private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return sharedPreferences.getString(key, defaultValue)
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        sharedPreferences.edit()
                .putString(key, value)
                .apply()
    }
}

Вы можете использоватьэто Activity следующим образом:

class MyActivity : AppCompatActivity() {
    var pref by PreferencesDelegate(this, "key")

    fun foo() {
        pref = "test"
        println(pref)
    }
}

Или с дополнительной функцией расширения для более приятного синтаксиса:

fun Activity.preference(key: String, defaultValue: String = ""): PreferencesDelegate {
    return PreferencesDelegate(this, key, defaultValue)
}

class MyActivity : AppCompatActivity() {
    var pref by preference("key")
}

Есть люди, которые уже имеютболее хорошие реализации того же самого с делегатами.Посмотрите, например, эту запись в блоге, эту и эту библиотеку.Вероятно, есть еще много, много других.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...