Как использовать SharedPreferences для сохранения нескольких значений?

Я разрабатываю приложение для словаря. В моем приложении я предполагаю, что пользователь хочет сохранить любимые слова. Я решил использовать SharedPreferences чтобы сохранить эти значения (я знаю, что SQLite и файлы лучше, но я застрял в "SharedPreferences", поэтому продолжайте с ним).

ниже приведен мой код:

@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();   
}

проблема в том, что он не сохраняет больше одного любимое слово. Я имею в виду, что сохраняется только одно любимое слово, а когда добавляется новое, предыдущее стирается.

Итак, как можно отредактировать приведенный выше код, чтобы решить эту проблему?

вы можете тут помочь? Большое спасибо.

6 ответов


вы можете сохранить несколько любимых в одном предпочтении, добавив многочисленные избранные в одной строке, каждый любимый элемент, разделенный запятой. Тогда вы можете использовать convertStringToArray метод преобразования его в строковый массив. Вот полный исходный код.
Используйте методы MyUtility для сохранения нескольких любимых элементов.

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

получить строковый массив всех сохраненных избранных

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

Сохраните эти методы в отдельной утилите класс!--9-->

 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;
    }
}

если вы добавить дополнительную избранное. Затем получите любимую строку из SharedPreference и добавить запятую+любимый предмет и сохранить его обратно в SharedPreference.
* Вы можете использовать любую другую строку для разделителя вместо запятой.


SharedPreferences работа с помощью простого ключа / значения, поэтому, когда вы предоставляете новое значение для того же ключа, Предыдущее значение перезаписывается. Единственный способ сделать то, что вы пытаетесь сделать, - использовать разные ключи, которые намекают на то, что вы, вероятно, не должны использовать SharedPreferences за то, что вы пытаетесь сделать.


Honeycomb добавил putStringSet метод, поэтому вы можете использовать это, если вам не нужно поддерживать что-либо меньшее, чем Honeycomb:

@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();
}

Если вам нужна поддержка устройств pre-Honeycomb, вам придется придумать свою собственную схему.

одна из возможностей-хранить слова как значения, разделенные запятыми, в одном предпочтении.

другое для создания нового ключа для каждого нового слова, "favourite1", "favourite2", "favourite3" и другие предпочтения, которые вы используете для запомните количество слов.


каждый раз, когда вы нажимаете кнопку, вы сохраняете любимое слово с уже присутствующим ключом:favorite и переопределить его. Чтобы сохранить более одного слова, вы должны сохранить слова с различными клавишами. Поэтому каждый раз, когда вы сохраняете любимое слово, вы можете сделать:

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

Ну, это потому, что фактическое хранилище предпочтений - это не список строк, а только один, поэтому всякий раз, когда вы говорите putString() вы перезаписываете Предыдущее значение. Хорошим способом хранения нескольких объектов в одной строке предпочтений является использование JSON. Просто сериализуйте значение, а затем напишите его им. Это также имеет преимущество преобразования непосредственно в объект любой сложности вы хотите. Посмотрите на использование Джексон Если вы решите пойти по этому маршруту.


вы можете использовать TreeMap (или другой тип списка, который реализует Serializable). Вот как я недавно обрабатывал список фаворитов. В TreeMap Favourite-это класс, который я использую. В вашем случае вы можете просто использовать TreeMap вместо этого.

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) {

    }
    }    
}

вы также можете избежать"::", что вы делаете для разделения значений.

надеюсь, что это поможет...