2012-01-29 14 views
10

Sto sviluppando un'applicazione per dizionari. Nella mia app, presumo che l'utente voglia salvare le parole preferite. Ho deciso di utilizzare SharedPreferences per salvare questi valori (sono consapevole del fatto che SQLite e i file sono migliori ma sono bloccato su "SharedPreferences", quindi continuate così).Come utilizzare SharedPreferences per salvare più di un valore?

Qui sotto è il mio codice:

@Override 
public void onClick(View v) {          
    SharedPreferences faves = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
    { 
     SharedPreferences.Editor editor = faves.edit(); 
     editor.putString("favourite", mSelectedDB + "::" + mCurrentWordId + "::" + mCurrentWord + ","); 
     editor.commit();  
    } 
    Log.i(CONTENT_TAG,"Favourite saved!"); 

    Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT); 
    toast.show(); 
} 

Il problema è che non mantiene più di una parola preferita. Voglio dire che una sola parola preferita viene salvata e quando ne viene aggiunta una nuova, la precedente viene cancellata.

Quindi, come è possibile modificare il codice precedente in modo che questo problema venga risolto?

Potete aiutarci? Grazie mille.

risposta

17

È possibile salvare più preferiti in una singola preferenza aggiungendo numerosi preferiti in una singola stringa, ogni elemento preferito separato da virgola. Quindi è possibile utilizzare il metodo convertStringToArray per convertirlo in Array di stringhe. Ecco il codice sorgente completo.
Utilizzare i metodi MyUtility per salvare più elementi preferiti.

  MyUtility.addFavoriteItem(this, "Sports"); 
      MyUtility.addFavoriteItem(this, "Entertainment"); 

ottenere String array di tutti i preferiti salvati

String[] favorites = MyUtility.getFavoriteList(this);// returns {"Sports","Entertainment"}; 

Salva questi metodi nella classe di servizio separato

public abstract class MyUtility { 

    public static boolean addFavoriteItem(Activity activity,String favoriteItem){ 
     //Get previous favorite items 
     String favoriteList = getStringFromPreferences(activity,null,"favorites"); 
     // Append new Favorite item 
     if(favoriteList!=null){ 
      favoriteList = favoriteList+","+favoriteItem; 
     }else{ 
      favoriteList = favoriteItem; 
     } 
     // Save in Shared Preferences 
     return putStringInPreferences(activity,favoriteList,"favorites"); 
    } 
    public static String[] getFavoriteList(Activity activity){ 
     String favoriteList = getStringFromPreferences(activity,null,"favorites"); 
     return convertStringToArray(favoriteList); 
    } 
    private static boolean putStringInPreferences(Activity activity,String nick,String key){ 
     SharedPreferences sharedPreferences = activity.getPreferences(Activity.MODE_PRIVATE); 
     SharedPreferences.Editor editor = sharedPreferences.edit(); 
     editor.putString(key, nick); 
     editor.commit();       
     return true;   
    } 
    private static String getStringFromPreferences(Activity activity,String defaultValue,String key){ 
     SharedPreferences sharedPreferences = activity.getPreferences(Activity.MODE_PRIVATE); 
     String temp = sharedPreferences.getString(key, defaultValue); 
     return temp;   
    } 

    private static String[] convertStringToArray(String str){ 
     String[] arr = str.split(","); 
     return arr; 
    } 
} 

Se si deve aggiungere preferiti in più. Quindi ottenere la stringa preferita da SharedPreference e aggiungere la virgola + elemento preferito e salvarla nuovamente in SharedPreference.
* È possibile utilizzare qualsiasi altra stringa per separatore anziché virgola.

+0

Grazie mille. Ma non ho ancora capito cosa fare a livello di programmazione. Ecco la forma di stringa SharedPreferences: ' dict_name :: 149272 :: go,'. Dove dovrebbe essere inserito il tuo codice? –

+0

@ user998032 Ho aggiunto il codice per spiegare come possiamo aggiungere più elementi preferiti. Puoi usare il codice così com'è, funzionerà per te. –

+0

@@ Muhammad Nabeel Arif: Grazie mille, ma ancora senza fortuna, mi dispiace! Voglio che il preferito venga salvato dopo onClick ma molti errori vengono generati dopo il codice modificato sopra. –

7

SharedPreferences funziona tramite semplice chiave/valore, quindi quando si fornisce un nuovo valore per la stessa chiave, il valore precedente viene sovrascritto. L'unico modo per fare ciò che stai cercando di fare è usare chiavi diverse, il che suggerisce che probabilmente non dovresti usare SharedPreferences per quello che stai cercando di fare.

5

Honeycomb aggiunto il metodo putStringSet, così si potrebbe usare che se non si dispone di supportare niente di meno che a nido d'ape:

@Override 
public void onClick(View v) { 
    SharedPreferences faves = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
    { 
     Set<String> faveSet = faves.getStringSet("favourite"); 
     faveSet.add(mSelectedDB + "::" + mCurrentWordId + "::" + mCurrentWord + ","); 
     SharedPreferences.Editor editor = faves.edit(); 
     editor.putStringSet("favourite", faveSet); 
     editor.commit(); 
    } 
    Log.i(CONTENT_TAG,"Favourite saved!"); 

    Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT); 
    toast.show(); 
} 

Se hai bisogno di supporto per i dispositivi pre-Honeycomb, si dovrà venire con il tuo schema personale.

Una possibilità è quella di memorizzare le parole come valori separati da virgola in una preferenza.

Un altro è generare una nuova chiave per ogni nuova parola "favourite1", "favourite2", "favourite3" e avere un'altra preferenza che si utilizza per memorizzare il numero di parole.

+0

Questo è vero, ma sfortunatamente sto facendo cose per dispositivi pre-Honeycomb. Grazie molto. –

2

Ogni volta che si fa clic sul pulsante si salva la parola preferita con la chiave già presente: favorite e la si sovrascrive. Per salvare più di una parola devi salvare le parole con chiavi diverse. Così ogni volta che si salva un parola preferita si potrebbe fare:

private static int incrementedValue = 0; 
... 
@Override 
public void onClick(View v) { 
    SharedPreferences faves = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 

    SharedPreferences.Editor editor = faves.edit(); 
    editor.putString("favourite" + incrementedValue, mSelectedDB + "::" + mCurrentWordId + "::" + mCurrentWord + ","); 
    editor.commit(); 

    Log.i(CONTENT_TAG,"Favourite saved!"); 

    Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT); 
    toast.show(); 
    incrementedValue++; 
} 
+0

Grazie mille. Mi piace il tuo approccio, ma quando è applicato, produce errori con ** ** incrementedValue, dicendo VariableDeclarationId previsto dopo ... –

+0

@ user998032 Ho modificato la mia risposta, ho dimenticato di aggiungere 'int' alla dichiarazione della variabile incrementedValue (non dimenticare di aggiungere la prima riga, la dichiarazione delle variabili, nella tua classe con il metodo onClick()). – Luksprog

+0

Grazie mille, slukian! Funziona ma non come mi aspettavo. SharePreferences salva ora le stringhe come: ' dict_name :: 157562 :: heap up, dict_name :: 31377 :: bell, dict_name :: 349333 :: tell, dict_name :: 349333 :: tell, dict_name :: 11834 :: am,', ma solo la prima parola preferita ("favourite0") viene caricata per la visualizzazione. –

1

Beh questo è perché l'archiviazione preferenza reale non è una lista di stringhe, solo una sola, in modo ogni volta che dite putString() si sovrascrive il valore precedente. Un buon modo per memorizzare più oggetti in una singola stringa di preferenza è usare JSON. Basta serializzare il valore e poi scriverglielo. Ha anche il vantaggio di convertire direttamente in un oggetto di qualsiasi complessità tu desideri. Cerca di usare Jackson se decidi di proseguire su questa rotta.

1

È possibile utilizzare un TreeMap (o altro tipo di lista che implementa Serializable). Ecco come ho gestito recentemente un elenco di preferiti. Nella TreeMap, Favorite è una classe che uso. Nel tuo caso, potresti semplicemente utilizzare TreeMap < Integer, String>.

private static TreeMap<Integer, Favourite> favourites; 

... 
... 
... 

// load favourites 
FileInputStream fis=null; 
ObjectInputStream ois = null; 
try { 
    fis = context.openFileInput(context.getString(R.string.favourites_file)); 
    try { 
    ois = new ObjectInputStream(fis); 
    favourites = (TreeMap<Integer, Favourite>) ois.readObject(); 
    } catch (StreamCorruptedException e) { 
    } catch (IOException e) { 
    } catch (ClassNotFoundException e) { 
    } 
} catch (FileNotFoundException e) { 
} finally { 
    try { 
    if (ois!=null){ 
     ois.close(); 
    } 
    } catch (IOException e) { 
    }  
} 

if (favourites==null){ 
    favourites = new TreeMap<Integer, Favourite>();  
} 

... 
... 
... 

// save favourites 
FileOutputStream fos=null; 
ObjectOutputStream oos=null; 
try { 
    fos = context.openFileOutput(context.getString(R.string.favourites_file), MODE_PRIVATE); 
    try { 
    oos = new ObjectOutputStream(fos); 
    oos.writeObject(favourites); 
    } catch (IOException e) { 
    } 
} catch (FileNotFoundException e) { 
} finally { 
    if (oos!=null){ 
    try { 
     oos.close(); 
    } catch (Exception e2) { 

    } 
    }  
} 

È anche possibile evitare la cosa "::" che si sta facendo per separare i valori.

Speranza che aiuti ...

+0

Grazie mille. Ho provato il simile prima ma ho avuto problemi quando sono elencati i preferiti. –

Problemi correlati