这是我的问题。我可以保存一个对象,但如果我保存另一个对象,它将删除前一个项目。我正在使用 gson lib 来保存我的项目。经过一些研究,我看到了这个 How to use SharedPreferences to save more than one values? 但由于我的自定义对象,我不能使用它,如果我使用 .toString(),我将无法取回我的原始项目。我知道这是用于保存对象的相同 key ,它将删除前一个对象,但我真的不知道每次保存项目时如何提供不同的 key 。
要添加的代码:
addFav.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (currentProduit.getIsAdded() ==0) {
SharedPreferences.Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String myJson = gson.toJson(currentProduit);
Log.i("INFO", "Value of saved data" + myJson);
prefsEditor.putString("myproduct", myJson);
prefsEditor.apply();
Toast.makeText(getApplicationContext(), "Data saved !", Toast.LENGTH_SHORT).show();
addFav.setText(R.string.delete_fav);
currentProduit.setIsAdded(1);
} else {
addFav.setText(R.string.add_fav);
currentProduit.setIsAdded(0);
SharedPreferences.Editor editor = mPrefs.edit();
editor.remove("myproduct").apply();
Toast.makeText(getApplicationContext(), "Data removed !", Toast.LENGTH_SHORT).show();
}
}
});
从其他 Activity 中恢复的代码:
String myJson = mPrefs.getString("myproduct", "");
Log.i("INFO", "Value of loaded data" + myJson);
if (myJson.isEmpty() && favProductList.isEmpty()) {
listview_R.setAdapter(null);
Log.i("INFO", "No items");
title.setText(getString(R.string.fav));
} else if (myJson.isEmpty() && favProductList != null) {
myCustomAdapterVersionR = new CustomAdapter_VersionR(getApplicationContext(), favProductList);
listview_R.setAdapter(myCustomAdapterVersionR);
} else {
Product savedProduct = gson.fromJson(myJson, Product.class);
favProductList.add(savedProduct);
Log.i("INFO", "Favorite was added");
myCustomAdapterVersionR = new CustomAdapter_VersionR(getApplicationContext(), favProductList);
listview_R.setAdapter(myCustomAdapterVersionR);
}
感谢您的帮助!顺便说一句,因为它没有保存很多项目,所以我没有使用 sqlite db,干杯!
编辑:我尝试了 Juan Cortés 的解决方案,但在取回共享首选项后出现此错误 --> 错误:不兼容的类型:CustomProduct[] 无法转换为列表,这是代码
if (fromPrefs.isEmpty() && favProductList.isEmpty()) {
listview_R.setAdapter(null);
Log.i("INFO", "No items");
title.setText(getString(R.string.fav));
} else {
//Product savedProduct = gson.fromJson(fromPrefs, Product.class);
//favProductList.add(savedProduct);
//Get the Object array back from the String `fromPrefs`
CustomProduct[] reInflated = gson.fromJson(fromPrefs,CustomProduct[].class);
Log.i("INFO", "Favorite was added");
myCustomAdapterVersionR = new CustomAdapter_VersionR(getApplicationContext(), reInflated); //error
listview_R.setAdapter(myCustomAdapterVersionR);
}
谢谢!
最佳答案
例如,作为一个过度简化的应用程序,您可以定义一个自定义类如下(当然,您必须根据自己的具体情况对其进行调整)。这个概念是创建一个自定义对象数组,将其转换为 json,然后存储。一旦您看到它,它真的很简单。
代码
Gson gson = new Gson();
//Create an array to work with it, dummy content
CustomProduct[] exampleList = new CustomProduct[10];
for(int i=0;i<10;i++){
exampleList[i] = new CustomProduct("string","number:"+i);
}
//Get a String representation of the objects
String forStoring = gson.toJson(exampleList);
//HERE you can store and retrieve to SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putString("myarrayofcustomobjects", forStoring).commit();
//Get the string back from the SharedPreferences
String fromPrefs = prefs.getString("myarrayofcustomobjects","");
//Get the Object array back from the String `fromPrefs`
CustomProduct[] reInflated = gson.fromJson(fromPrefs,CustomProduct[].class);
注意事项
如果数组中已经有一组对象,则需要如上所示扩充数组,用这些元素+要添加的元素创建一个新数组,再次将它们转换为字符串,然后存储它们。一旦这变得太麻烦,您将转向另一种方法来为您的应用程序保留数据,但只要没有那么多,就应该没问题。
假设
为了让它工作,我假设您有一个名为 CustomProduct
的自定义对象,其定义如下:
public class CustomProduct {
String field1,field2;
public CustomProduct(String field1, String field2){
super();
this.field1 = field1;
this.field2 = field2;
}
@Override
public String toString() {
return "CustomProduct [field1="+field1+",field2="+field2+"]";
}
}
更新
用户想要在 ListView 中显示结果。您可以像下面这样定义自定义适配器以使其工作。现在是我建议您尽快转向 RecyclerView
而不是 ListView
的时候了,但首先要解决您遇到的问题,让它发挥作用,然后再对其进行改进
public class CustomAdapter extends BaseAdapter{
private CustomProduct[] mProducts;
private LayoutInflater mInflater;
public CustomAdapter(Context context, CustomProduct[] products){
mProducts = products;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return mProducts.length;
}
public CustomProduct getItem(int i) {
return mProducts[i];
}
public long getItemId(int i) {
return i;
}
public View getView(int i, View convertView, ViewGroup parent) {
//Purposely not doing view recycling for sake of clarity
View row = mInflater.inflate(R.layout.custom_row,parent,false);
//Set the data from the row
((TextView)row.findViewById(R.id.field1)).setText(getItem(i).field1);
((TextView)row.findViewById(R.id.field2)).setText(getItem(i).field2);
//Return the view
return row;
}
}
通过将此适配器设置为您的 ListView
并创建布局(它只包含两个具有给定 ID 的 TextView ),您将获得以下结果。您可以尝试在第一次运行后删除它创建数据的部分,只保留它获取数据的部分以确保它持久化。
关于android - 无法在 SharedPreferences 中保存多个自定义对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36883734/