Как использовать 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();   
}

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

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

Можете ли вы, ребята, помочь? Большое вам спасибо.

Ответ 1

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

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

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

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

Сохраните эти методы в отдельном классе Utility

 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.
* Вы можете использовать любую другую строку для разделителя вместо запятой.

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

Каждый раз, когда вы нажимаете кнопку, вы сохраняете любимое слово с уже существующей клавишей: 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++;
}

Ответ 5

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

Ответ 6

Вы можете использовать TreeMap (или другой тип списка, который реализует Serializable). Вот как я недавно обработал список избранных. В TreeMap, Favorite - это класс, который я использую. В вашем случае вы можете просто использовать 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) {

    }
    }    
}

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

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