user1244932
user1244932

Reputation: 8112

usage of PreferenceFragment and architecture

In my application I have preference: "pref1" with possible values 0, 1, 2. I hold them with help of SharedPreferences class.

  1. And I want to provide a user interface to change it. I create class SettingFragment extends PreferenceFragment and xml file with PreferenceScreen root. In xml file I have to set android:key field to bind UI and SharedPreferences.

  2. To change my application behaviour after user change "pref1" I have to implement OnSharedPreferenceChangeListener.

  3. Also at start of the program I need to get value of "pref1", to sync state of program according to saved preferences.

So there are 3 places which I should change when I want add/remove/modify unit of setting of my application. Looks bad. Another option is to write a class that have a member variable of SharedPreferences type and hide all SharedPreferences keys and give simple set/get methods to get the preferences. But in this case I have to use normal tool for android UI: layouts.

So is any way to use PreferenceFragment without spreading knowledge about the internal structure of preference storage (names of keys, default values, their types) into several places, or better to use normal layouts?

Upvotes: 4

Views: 187

Answers (2)

abhishesh
abhishesh

Reputation: 3326

You don't need to have separate shared preference keys for preferences in PreferenceFragment. Android framework automatically saves it in shared preference if you have specified it as persistent (android:persistent=true). By default, persistent flag is true. As per docs :

PreferenceFragment shows a hierarchy of Preference objects as lists. These preferences will automatically save to SharedPreferences as the user interacts with them.

For your case you can use list preference

    <ListPreference
            android:key="pref1"
            android:title="title"
            android:summary="description"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference"
            android:defaultValue="1"
            android:dialogTitle="dialog title" />

Note that defaultvalue should be entryvalues_list_preference element.

If you have to perform some specific function when preference value changes then you need to add preference change listener.

ListPreference preference1 = (ListPreference) findPreference ("pref1");

    ListPreference preference1 = (ListPreference) findPreference ("pref1");

    performAction(preference1.getValue());
    preference1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
    /**
     * Called when a Preference has been changed by the user. This is
     * called before the state of the Preference is about to be updated and
     * before the state is persisted.
     * 
     * @param preference The changed Preference.
     * @param newValue The new value of the Preference.
     * @return True to update the state of the Preference with the new value.
     */
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            performAction(String.valueOf(newValue));
            return true;
        }
    });

private void performAction(String type) {
    switch (type){
        case "0": // when 0 value is selected

            break;
        case "1": //when 1 value is selected

            break;
        case "2": //when 2 value is selected

            break;
    }
}

If you don't need any custom operation with preferences, then you only need to add/remove in preference xml file and should not worry about initialization/updation of preference as Android framework will handle it for you.

Upvotes: 0

Dibzmania
Dibzmania

Reputation: 1994

As you have already highlighted in your question, the 3 parts of having settings based on SharedPreference is defining - 1. A UI layout for the user to see and change settings. 2. Listen for Settings changes. 3. Read Settings when initialising UI.

You cannot actually do away with any of the parts, without effecting your functionality. But you can arrange your code in a way so as to minimise the number of files (or places in code) where you have to modify when you want to say add a new Settings. There is nothing you can do to remove the UI building part. But listening and reading settings values can be wrapped in a globally accessible Singleton (from everywhere in your). You can initialise this single when your App initialises and can have simple set/get interfaces. You still need to define some kind of interface so that you can listen for changes. Let the singleton class have API's to set/remove these interfaces. Consumers can set/remove these interfaces and you can decide what the interface should look like.

Upvotes: 2

Related Questions