views:

215

answers:

3

Hi all, I'm new to using the PreferenceActivity.

Task: Allow user to choose the program layout from the Preferences

Problem: Selecting an option in the PreferenceList causes a NullPointerException

Exception arises: At android.preference.ListPreference.onDialogClosed()

alt text

(Shortened) Code:

private static final String PREF_LAYOUT_KEY = "PrefLayout";
private static final int DEFAULT_LAYOUT = LayoutHelper.LAYOUT_DOUBLE ;
private static int mListLayout = DEFAULT_LAYOUT ;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
    pref.registerOnSharedPreferenceChangeListener(this);
    mListLayout = pref.getInt(PREF_LAYOUT_KEY, DEFAULT_LAYOUT);
}

@Override
public void onSharedPreferenceChanged(SharedPreferences pref,
        String key) {

    Log.v(TAG, "OnSharedPreferencesChanged run" ); // TODO Testing Purposes

    if( key.equals( PREF_LAYOUT_KEY ) ){
        mListLayout = pref.getInt(key, DEFAULT_LAYOUT);
    }
}

[PreferenceActivity]

public class Preferences extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.pref);
    }
}

[res/xml/pref.xml]

<PreferenceCategory
    android:title="@string/pref_cat1_title">

    <ListPreference
        android:title="@string/pref_layout_name"
        android:summary="@+id/pref_chosen_layout"
        android:key="PrefLayout"
        android:entries="@array/prefLayoutOptions"
        android:entryValues="@array/prefLayoutOptionsValues"
    />
</PreferenceCategory>

[Strings.xml]

<string name="pref_cat1_title">Layout</string>
    <string name="pref_layout_name">"Layout of list"</string>
        <array name="prefLayoutOptions">
            <item>Layout 1 (single)</item>
            <item>Layout 2 (double)</item>
            <item>Layout 3 (triple)</item>
            <item>Layout 4 (quad)</item>
        </array>
        <array name="prefLayoutOptionsValues">
            <item>50</item>
            <item>51</item>
            <item>52</item>
            <item>53</item>
        </array>

The bit of code that logs OnSharedPreferencesChanged being run never gets there.

Can anybody see where I've gone wrong?

EDIT. Here's the top of the stack trace:

E/AndroidRuntime( 2707): java.lang.NullPointerException
E/AndroidRuntime( 2707):        at android.preference.ListPreference.onDialogClosed(ListPreference.java:218)
E/AndroidRuntime( 2707):        at android.preference.DialogPreference.onDismiss(DialogPreference.java:384)
E/AndroidRuntime( 2707):        at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1047)
E/AndroidRuntime( 2707):        at android.os.Handler.dispatchMessage(Handler.java:99)
A: 

I think you need to set preference change listener for your preferences right at the activity, try putting that to the activity's onCreate:

    Map<String, ?> prefs = this.getPreferenceManager().getSharedPreferences().getAll();
    for (String preferenceName : prefs.keySet()) {
        Preference p = this.findPreference(preferenceName);
        if (p != null) {
            Object value = prefs.get(preferenceName);
            p.setOnPreferenceChangeListener(this);
        }
    }
Konstantin Burov
Which activity are you referring to? It has errors for both the main activity or the Preferences activity
HXCaine
On second thought, I would prefer to find the root of the problem than to do this kind of hack to fix it. Although it has tipped me off to hunt down another bit of access to shared preferences which may be interfering
HXCaine
+1  A: 
mListLayout = pref.getInt(PREF_LAYOUT_KEY, DEFAULT_LAYOUT);

That will fail, because the preference is a string, not an int.

<array name="prefLayoutOptions">
<array name="prefLayoutOptionsValues">

Change these to <string-array>. Here is a sample project demonstrating the use of a ListPreference.

CommonsWare
Changing the arrays to string-arrays seems to fix the problem, but I'd have to change my classes to deal with Strings instead. I'd really like to store these preferences as ints, do you know what I would need to change to have everything working with ints?
HXCaine
@T3Roar: `ListPreference` supports strings. If you want something else, you will need to write your own preference class.
CommonsWare
or you can have a hashmap in your class to map the string with the ints if that's really what you need.
Sephy
+1  A: 

Hi,

I encountered the same problem. It seems you can only use string values: http://code.google.com/p/android/issues/detail?id=2096

/Håkan

hajons

related questions