LiveData with shared preferences

前端 未结 7 1560
轮回少年
轮回少年 2020-12-15 05:51

I have a settings screen where I am setting some values. When I set those values it gets saved in shared preferences and these values are needed in my request to the network

相关标签:
7条回答
  • 2020-12-15 06:04

    Add below dependency in build.gradle(:app)

     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.6"  // replace with updated version 
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.6"// replace with updated version 
    

    Add Below code inyYour preference class/utils

    private var mPrefs: SharedPreferences =
            mContext.getSharedPreferences(AppConstant.PREF_NAME, Context.MODE_PRIVATE)
    
     private val _constSate = MutableStateFlow(mPrefs.getBoolean(IS_NOTIFY,false))
    
    // function for set data to preference and add to Stateflow. 
    
    fun setData(isNotify: Boolean){
           // mPrefs = instance of your preference 
            mPrefs.edit().putBoolean(IS_NOTIFY, isNotify).apply()
            _constSate.value = isNotify
        }
    
    //function for get observer/flow/live boolean value 
    
    fun getNotifyFlow() : StateFlow<Boolean> = _constSate
    

    //get your observer/flow/live value on other class e.g MainActivity.class etc..

     CoroutineScope(Dispatchers.Main).launch{      
         appPreferences.getNotifyFlow().collect{
                       if (it){
                        Log.d("jai","true")
                       }else{
                         Log.d("jai","false")
                       }
                    }
          }
    
    0 讨论(0)
  • 2020-12-15 06:17

    I've create a pure kotlin lib to do this - https://github.com/Jintin/PreferencesExtension

    All we need to do is something like:

    val preferenceLiveData = preference.liveData<String>(MY_KEY)
    
    preferenceLiveData.observe(this) {
        // get update here
    }
    

    And sure the preferenceLiveData can be inside ViewModel and let Activity/Fragment observe it. Check out the example here: Activity, ViewModel

    0 讨论(0)
  • 2020-12-15 06:18

    Android recently released DataStore which is:

    Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects with protocol buffers. DataStore uses Kotlin coroutines and Flow to store data asynchronously, consistently, and transactionally.

    If you're currently using SharedPreferences to store data, consider migrating to DataStore instead.

    So here is the breakdown:

    In the build.gradle of the project:

    android {
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        
        kotlinOptions {
            jvmTarget = JavaVersion.VERSION_1_8.toString()
        }
    }
    
    dependencies {
        ...
        implementation "androidx.datastore:datastore-preferences:1.0.0-alpha04"
    }
    

    The database class would look like:

    class SettingsSharedPreference private constructor(context: Context) {
    
        private val dataStore = context.createDataStore(name = "settings")
    
        companion object {
    
            val SCREEN_ORIENTATION = preferencesKey<String>("screen_orientation")
    
            @Volatile
            private var instance: SettingsSharedPreference? = null
    
            private val lock = Any()
    
            operator fun invoke(context: Context) = instance ?: synchronized(lock) {
                instance ?: SettingsSharedPreference(context).also { instance = it }
            }
        }
    
        val screenOrientationFlow: Flow<String> = dataStore.data
            .map { preferences ->
                preferences[SCREEN_ORIENTATION] ?: "landscape"
            }
    
        //TODO: You should use enum for screenOrientation, this is just an example
        suspend fun setScreenOrientation(screenOrientation: String) {
            dataStore.edit { preferences ->
                preferences[SCREEN_ORIENTATION] = screenOrientation
            }
        }
    }
    

    In the Activity:

    val settingsSharedPreference by lazy {
        SettingsSharedPreference.invoke(this)
    }
    ...
    settingsSharedPreference.setScreenOrientation("portrait")    
    ...
    settingsSharedPreference.screenOrientationFlow.asLiveData().observe(this) { screenOrientation ->
        ...
    }
    
    0 讨论(0)
  • 2020-12-15 06:23

    i see your challenge is calling Shared Preferences Value when API Calling in ViewModel or LiveData.

    You may define your shared preference as global in Application class ( so it will be global)

    public class MyApplication extends Application {
       public static AppPreferences shared_preference;
    
       /*On Create Application Create AppPreferences*/
       @Override
       public void onCreate() {
         super.onCreate();
         shared_preference = AppPreferences.getInstance(this);
       }
    }
    

    And you may update or save value by calling Shared Preference in your ViewModel

    /*Save to Shared Preferences*/
    MyApplication.shared_preference.setLogin(true);
    

    Wish this help you, cause i see your problem there, This is works for me and able to insert param in API Call.

    0 讨论(0)
  • 2020-12-15 06:27

    Assuming your network request is already providing you a LiveData class. For example with Retrofit and a CallAdapter like LiveDataCallAdapter.

    Once you have the last observed value by either:

    • Applying a listener for shared preferences OnSharedPreferenceChangeListener, as you already mentioned, to update a MutableLiveData
    • Or using a SharedPreferences LiveData like rharter/SharedPreferenceLiveData.kt

    Then you can apply the previous LiveData to either:

    • A Transformations.switchMap as in UserViewModel.kt (related part quoted below)
    • Or as parameter for MediatorLiveData addSource method.

    This is the related example for the Transformations.switchMap in UserViewModel.kt:

    private val _login = MutableLiveData<String>()
    val login: LiveData<String>
        get() = _login
    val repositories: LiveData<Resource<List<Repo>>> = Transformations
        .switchMap(_login) { login ->
            if (login == null) {
                AbsentLiveData.create()
            } else {
                repoRepository.loadRepos(login)
            }
        }
    
    0 讨论(0)
  • 2020-12-15 06:28

    The following awesome piece of code is LiveData Implementation of SharedPreference. It works perfectly.

    package com.chargingwatts.chargingalarm.util.preference;
    
    import android.arch.lifecycle.LiveData
    import android.content.SharedPreferences
    
    abstract class SharedPreferenceLiveData<T>(val sharedPrefs: SharedPreferences,
                                               val key: String,
                                               val defValue: T) : LiveData<T>() {
    
        private val preferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
            if (key == this.key) {
                value = getValueFromPreferences(key, defValue)
            }
        }
    
        abstract fun getValueFromPreferences(key: String, defValue: T): T
    
        override fun onActive() {
            super.onActive()
            value = getValueFromPreferences(key, defValue)
            sharedPrefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
        }
    
        override fun onInactive() {
            sharedPrefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
            super.onInactive()
        }
    }
    
    class SharedPreferenceIntLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Int) :
            SharedPreferenceLiveData<Int>(sharedPrefs, key, defValue) {
        override fun getValueFromPreferences(key: String, defValue: Int): Int = sharedPrefs.getInt(key, defValue)
    }
    
    class SharedPreferenceStringLiveData(sharedPrefs: SharedPreferences, key: String, defValue: String) :
            SharedPreferenceLiveData<String>(sharedPrefs, key, defValue) {
        override fun getValueFromPreferences(key: String, defValue: String): String = sharedPrefs.getString(key, defValue)
    }
    
    class SharedPreferenceBooleanLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Boolean) :
            SharedPreferenceLiveData<Boolean>(sharedPrefs, key, defValue) {
        override fun getValueFromPreferences(key: String, defValue: Boolean): Boolean = sharedPrefs.getBoolean(key, defValue)
    }
    
    class SharedPreferenceFloatLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Float) :
            SharedPreferenceLiveData<Float>(sharedPrefs, key, defValue) {
        override fun getValueFromPreferences(key: String, defValue: Float): Float = sharedPrefs.getFloat(key, defValue)
    }
    
    class SharedPreferenceLongLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Long) :
            SharedPreferenceLiveData<Long>(sharedPrefs, key, defValue) {
        override fun getValueFromPreferences(key: String, defValue: Long): Long = sharedPrefs.getLong(key, defValue)
    }
    
    class SharedPreferenceStringSetLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Set<String>) :
            SharedPreferenceLiveData<Set<String>>(sharedPrefs, key, defValue) {
        override fun getValueFromPreferences(key: String, defValue: Set<String>): Set<String> = sharedPrefs.getStringSet(key, defValue)
    }
    
    fun SharedPreferences.intLiveData(key: String, defValue: Int): SharedPreferenceLiveData<Int> {
        return SharedPreferenceIntLiveData(this, key, defValue)
    }
    
    fun SharedPreferences.stringLiveData(key: String, defValue: String): SharedPreferenceLiveData<String> {
        return SharedPreferenceStringLiveData(this, key, defValue)
    }
    
    fun SharedPreferences.booleanLiveData(key: String, defValue: Boolean): SharedPreferenceLiveData<Boolean> {
        return SharedPreferenceBooleanLiveData(this, key, defValue)
    }
    
    fun SharedPreferences.floatLiveData(key: String, defValue: Float): SharedPreferenceLiveData<Float> {
        return SharedPreferenceFloatLiveData(this, key, defValue)
    }
    
    fun SharedPreferences.longLiveData(key: String, defValue: Long): SharedPreferenceLiveData<Long> {
        return SharedPreferenceLongLiveData(this, key, defValue)
    }
    
    fun SharedPreferences.stringSetLiveData(key: String, defValue: Set<String>): SharedPreferenceLiveData<Set<String>> {
        return SharedPreferenceStringSetLiveData(this, key, defValue)
    }
    
    0 讨论(0)
提交回复
热议问题