I am developing a dictionary app. In my app, I assume that user wants to save favourite words. I have decided to use SharedPreferences to save these values (I am aware that SQLite and files are better but I am stuck to "SharedPreferences", so keep on with it).
我正在开发一个字典应用程序。在我的应用程序中,我假设用户想保存最喜欢的单词。我已经决定使用SharedPreferences来保存这些值(我知道SQLite和文件更好,但是我坚持“SharedPreferences”,所以继续使用它)。
Here below is my code:
下面是我的代码:
@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();
}
The problem is that it does not retain more than one favourite word. I mean only one favourite word is saved and when a new one is added, the previous is erased.
问题是它没有保留超过一个最喜欢的词。我的意思是只有一个最喜欢的词被保存,当一个新的词被添加时,之前的词被删除。
So, how can the above code be edited so that this problem is solved?
那么,如何对上面的代码进行编辑,从而解决这个问题呢?
Can you guys there help? Thank you very much.
你们能帮忙吗?非常感谢。
6 个解决方案
#1
18
You can save multiple favorites in a single preference by adding numerous favorites in a single string, each favorite item separated by comma. Then you can use convertStringToArray
method to convert it into String Array. Here is the full source code.
Use MyUtility Methods to save multiple favorite items.
您可以将多个收藏项保存在一个首选项中,方法是在一个字符串中添加多个收藏项,每个收藏项用逗号分隔。然后可以使用convertStringToArray方法将其转换为String数组。这是完整的源代码。使用MyUtility方法保存多个最喜欢的项目。
MyUtility.addFavoriteItem(this, "Sports");
MyUtility.addFavoriteItem(this, "Entertainment");
get String array of all favorites saved
获取保存的所有收藏的字符串数组。
String[] favorites = MyUtility.getFavoriteList(this);// returns {"Sports","Entertainment"};
Save these methods in separate Utility class
将这些方法保存在单独的实用程序类中。
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;
}
}
If you have to add extra favorites. Then get favorite string from SharedPreference
and append comma+favorite item and save it back into SharedPreference
.
* You can use any other string for separator instead of comma.
如果你必须添加额外的收藏。然后从SharedPreference和append逗号+favorite item中获取favorite字符串,并将其保存为SharedPreference。*您可以使用任何其他字符串作为分隔符,而不是逗号。
#2
7
SharedPreferences
work via simple key/value so when you provide a new value for the same key, the previous value is overwritten. The only way to do what you're trying to do is to use different keys, which sort of hints towards the fact that you probably shouldn't be using SharedPreferences
for what you're trying to do.
SharedPreferences通过简单的键/值工作,因此当您为相同的键提供一个新值时,将覆盖先前的值。做你想做的事情的唯一方法是使用不同的键,这暗示了你可能不应该用SharedPreferences来做你想做的事情。
#3
5
Honeycomb added the putStringSet
method, so you could use that if you don't have to support anything less than Honeycomb:
蜂巢增加了putStringSet方法,所以你可以使用它,如果你不需要支持任何少于蜂巢的东西:
@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();
}
If you need support for pre-Honeycomb devices, you will have to come up with your own scheme.
如果你需要对蜂窝设备的支持,你必须想出你自己的方案。
One possibility is to store the words as comma-separated values in one preference.
一种可能是将单词作为逗号分隔的值存储在一个首选项中。
Another is to generate a new key for each new word, "favourite1", "favourite2", "favourite3" and have another preference you use to store the number of words.
另一种方法是为每个新单词生成一个新键,“preferences 1”,“preference”,“preference”,还有另外一个用来存储单词数量的首选项。
#4
2
Every time you click the button you save the favorite word with the already present key: favorite
and you override it. To save more than one word you have to save the words with different keys. So every time you save a favorite word you could do:
每当你点击按钮时,你就会用已经存在的键保存你最喜欢的单词:你最喜欢的,你重写它。要保存多个单词,您必须使用不同的键保存这些单词。所以每次你存下一个你最喜欢的词,你就可以:
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
1
Well that's because the actual preference storage is not a List of strings, just a single one, so whenever you say putString()
you overwrite the previous value. A good way to store multiple objects in a single preference string is to use JSON. Simply serialize the value and then write it to them. It also has the benefit of converting directly back into an object of whatever complexity you wish. Look into using Jackson if you decide to go on this route.
这是因为实际的首选项存储不是一个字符串列表,而是一个字符串,所以每当你说putString()时,你就重写了先前的值。在一个首选项字符串中存储多个对象的一个好方法是使用JSON。只需序列化该值,然后将其写入它们。它还可以直接转换为您希望的任何复杂的对象。如果你决定走这条路,就考虑用杰克逊。
#6
1
You could use a TreeMap (or other type of list which implements Serializable). Here's how I handled a list of favourites recently. In the TreeMap, Favourite is a class I use. In your case, you could just use TreeMap<Integer, String> instead.
您可以使用TreeMap(或实现Serializable的其他类型的列表)。下面是我最近处理最爱列表的方法。在TreeMap中,我使用的类是favorite。在您的例子中,您可以使用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) {
}
}
}
You can also avoid the "::" thing you're doing to separate values.
您还可以避免“:”的事情,您正在做的分离值。
Hope that helps...
希望这有助于……
#1
18
You can save multiple favorites in a single preference by adding numerous favorites in a single string, each favorite item separated by comma. Then you can use convertStringToArray
method to convert it into String Array. Here is the full source code.
Use MyUtility Methods to save multiple favorite items.
您可以将多个收藏项保存在一个首选项中,方法是在一个字符串中添加多个收藏项,每个收藏项用逗号分隔。然后可以使用convertStringToArray方法将其转换为String数组。这是完整的源代码。使用MyUtility方法保存多个最喜欢的项目。
MyUtility.addFavoriteItem(this, "Sports");
MyUtility.addFavoriteItem(this, "Entertainment");
get String array of all favorites saved
获取保存的所有收藏的字符串数组。
String[] favorites = MyUtility.getFavoriteList(this);// returns {"Sports","Entertainment"};
Save these methods in separate Utility class
将这些方法保存在单独的实用程序类中。
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;
}
}
If you have to add extra favorites. Then get favorite string from SharedPreference
and append comma+favorite item and save it back into SharedPreference
.
* You can use any other string for separator instead of comma.
如果你必须添加额外的收藏。然后从SharedPreference和append逗号+favorite item中获取favorite字符串,并将其保存为SharedPreference。*您可以使用任何其他字符串作为分隔符,而不是逗号。
#2
7
SharedPreferences
work via simple key/value so when you provide a new value for the same key, the previous value is overwritten. The only way to do what you're trying to do is to use different keys, which sort of hints towards the fact that you probably shouldn't be using SharedPreferences
for what you're trying to do.
SharedPreferences通过简单的键/值工作,因此当您为相同的键提供一个新值时,将覆盖先前的值。做你想做的事情的唯一方法是使用不同的键,这暗示了你可能不应该用SharedPreferences来做你想做的事情。
#3
5
Honeycomb added the putStringSet
method, so you could use that if you don't have to support anything less than Honeycomb:
蜂巢增加了putStringSet方法,所以你可以使用它,如果你不需要支持任何少于蜂巢的东西:
@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();
}
If you need support for pre-Honeycomb devices, you will have to come up with your own scheme.
如果你需要对蜂窝设备的支持,你必须想出你自己的方案。
One possibility is to store the words as comma-separated values in one preference.
一种可能是将单词作为逗号分隔的值存储在一个首选项中。
Another is to generate a new key for each new word, "favourite1", "favourite2", "favourite3" and have another preference you use to store the number of words.
另一种方法是为每个新单词生成一个新键,“preferences 1”,“preference”,“preference”,还有另外一个用来存储单词数量的首选项。
#4
2
Every time you click the button you save the favorite word with the already present key: favorite
and you override it. To save more than one word you have to save the words with different keys. So every time you save a favorite word you could do:
每当你点击按钮时,你就会用已经存在的键保存你最喜欢的单词:你最喜欢的,你重写它。要保存多个单词,您必须使用不同的键保存这些单词。所以每次你存下一个你最喜欢的词,你就可以:
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
1
Well that's because the actual preference storage is not a List of strings, just a single one, so whenever you say putString()
you overwrite the previous value. A good way to store multiple objects in a single preference string is to use JSON. Simply serialize the value and then write it to them. It also has the benefit of converting directly back into an object of whatever complexity you wish. Look into using Jackson if you decide to go on this route.
这是因为实际的首选项存储不是一个字符串列表,而是一个字符串,所以每当你说putString()时,你就重写了先前的值。在一个首选项字符串中存储多个对象的一个好方法是使用JSON。只需序列化该值,然后将其写入它们。它还可以直接转换为您希望的任何复杂的对象。如果你决定走这条路,就考虑用杰克逊。
#6
1
You could use a TreeMap (or other type of list which implements Serializable). Here's how I handled a list of favourites recently. In the TreeMap, Favourite is a class I use. In your case, you could just use TreeMap<Integer, String> instead.
您可以使用TreeMap(或实现Serializable的其他类型的列表)。下面是我最近处理最爱列表的方法。在TreeMap中,我使用的类是favorite。在您的例子中,您可以使用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) {
}
}
}
You can also avoid the "::" thing you're doing to separate values.
您还可以避免“:”的事情,您正在做的分离值。
Hope that helps...
希望这有助于……