2010-08-22 14 views
7

Sono nuovo nell'utilizzo di PreferenceActivity.PreferenceActivity fornisce NullPointerException quando l'opzione è selezionata da ListPreference

Task: Consenti all'utente di scegliere il layout del programma da Preferenze

Problema: selezionando un'opzione nella PreferenceList provoca un NullPointerException nasce

Eccezione: A android.preference.ListPreference .onDialogClosed()

alt text

(abbreviato) Codice:

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> 

Il bit di codice che registra OnSharedPreferencesChanged in esecuzione mai arriva.

Qualcuno può vedere dove ho sbagliato?

MODIFICA. Ecco la parte superiore della traccia dello stack:

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) 
+0

Lei dice che l'eccezione è in .onDialogClosed(), ma non riesco a vedere questo metodo nel codice ... – Sephy

+0

Puoi pubblicare un Uscita LogCat? –

+2

Appena aggiunta la traccia dello stack. @Sephy: L'onDialogClosed proviene da ListPreference, non dal mio codice – HXCaine

risposta

19
mListLayout = pref.getInt(PREF_LAYOUT_KEY, DEFAULT_LAYOUT); 

Ciò fallirà, perché la preferenza è una stringa, non un int.

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

Cambiare in <string-array>. Ecco a sample project che dimostra l'uso di un ListPreference.

+0

Cambiare gli array in array di stringhe sembra risolvere il problema, ma dovrei cambiare le mie classi per gestire invece le stringhe. Mi piacerebbe davvero memorizzare queste preferenze come ints, sai cosa avrei bisogno di cambiare per avere tutto ciò che funziona con ints? – HXCaine

+5

@ T3Roar: 'ListPreference' supporta le stringhe. Se vuoi qualcos'altro, dovrai scrivere la tua classe di preferenza. – CommonsWare

+0

oppure puoi avere una hashmap nella tua classe per mappare la stringa con gli interi se è davvero ciò di cui hai bisogno. – Sephy

0

Credo che è necessario impostare il cambiamento preferenza ascoltatore per le tue preferenze proprio alla attività, provare a mettere che a onCreate la propria attività:

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); 
     } 
    } 
+0

A quale attività ti riferisci? Ha degli errori sia per l'attività principale che per l'attività Preferenze – HXCaine

+0

A pensarci bene, preferirei trovare la radice del problema piuttosto che fare questo tipo di hack per risolverlo. Anche se mi ha dato la possibilità di dare un altro po 'di accesso alle preferenze condivise che potrebbero interferire – HXCaine

Problemi correlati