Preference change listener but AFTER the internal state has changed android

727 Views Asked by At

I have a SettingsFragment which extends PreferenceFragmentCompat and the preference.xml

class SettingsFragment : PreferenceFragmentCompat() {

   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = super.onCreateView(inflater, container, savedInstanceState)

        preferenceManager.findPreference<Preference>(USER_CLOUD_PROXY)?.let {
            it.setOnPreferenceChangeListener { _, _ ->
                // mainViewModel.resetConnection()
                true
            }
        }

        return view
    }

}

and xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory android:title="User settings">
        <SwitchPreference
            android:defaultValue="true"
            android:enabled="true"
            android:key="user_cloud_proxy"
            android:title="Use cloud proxy" />
    </PreferenceCategory>

</PreferenceScreen>

The switch button indicates with which URL my app has to connect to a webSocket server. So when the user changes the switch state i want to reset the connection through a function. Later in the function i read the sharedPreference value to choose the URL. However, the it.setOnPreferenceChangeListener get called before the internal state has changed, which means that i dont read the newValue, but the old.

Is there a callback that gets called AFTER the internal value has changed?

4

There are 4 best solutions below

0
Dinkar Kumar On BEST ANSWER

There is OnPreferenceChangeInternalListener.onPreferenceChange which is Called when this Preference has changed, but this callback is for internal usage only.

enter image description here

enter image description here

So yes, there is no other callback that gets called after the internal value has changed. OnPreferenceChangeListener.onPreferenceChange is the only one you can use.

One thing you can do, if you don't want to call the function directly from the callback taking the newValue from it, then you can save the new value in SharedPref manually and then call the function which can use your logic of reading the value from sharedpref and proceeding further.

1
AudioBubble On

Adding to dinkar_kumar's answer you can try to implement OnSharedPreferenceChangeListener and I think you can use onSharedPreferenceChanged to use your logic further.

0
james04 On

Thank you, well informed! i will do this the way u propose. Seems fine

0
Kosrat D. Ahmad On

As I have tested, if you have an async task, it will be run after the internal state has changed like below:

Kotlin Sample Code:

Preference.OnPreferenceChangeListener { _, _ ->
    afterChange()
    true
}


fun afterChange() {
    // coroutine async task
    MainScope().launch {
        // It will run after the preference has been changed.
    }
}