1

Here is my issue. I can save an object, but if I save another object, it will erase the previous item. I'm using gson lib to save my items. After some researches I've seen this How to use SharedPreferences to save more than one values? But I can't use it because of my custom objects, if I use .toString(), I will not be able to get back my original item. I know that's it's the same key used to save object that will erase the previous one but I dont really know how to give a different key every time I will save an item.

Code to add :

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

Code to get back from other 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);
    }

Thanks for helping ! Btw, since it's not saving a lot of items, I didnt use sqlite db, cheers !

EDIT: I tried Juan Cortés solution, but I have this error after getting back the shared preferences --> error: incompatible types: CustomProduct[] cannot be converted to List, here is the code

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

Thanks !

Community
  • 1
  • 1
Jay
  • 144
  • 1
  • 2
  • 14

1 Answers1

1

As an overly simplified app for example, you could define a custom class as follows (of course you'll have to adapt it to your particulars). The concept is create an array of custom objects, convert it to json, store it. It's really straightforward once you see it.

The code

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

Notes

If you already have a set of objects in an array, you'll need to inflate the array as shown above, create a new array with those elements + the one you want to add, convert them to a string again, and store them. Once this becomes too much of a hassle, you'll move to another means of persisting data for you app, but for as long as there are not that many, it should be ok.

Assuming

To get this to work, I'm assuming you have a Custom object named CustomProduct with the following definition:

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

Update

User wants to show the results in a listview. You can define a custom adapter like the following to get it to work. Let this be the time for me to advise you to soon move towards RecyclerView instead of ListView but first tackle the problem you have, make it work, then improve upon it

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

By setting this adapter to your ListView and creating the layout (which simply consists in two textviews with the given ids) you will get the following result. You can try removing the part where it creates the data after it's run the first time and leaving only the part where it fetches the data to ensure it's persisted.

enter image description here

Juan Cortés
  • 20,634
  • 8
  • 68
  • 91
  • Thanks for you answer, I'm trying it right away, so if I understand, your CustomProduct[] exampleList = new CustomProduct[10]; means that you gave a predefined size to the favorite list ? Should I put outside of my if block as well ? – Jay Apr 27 '16 at 09:00
  • In my overly simplified example I did give it a set size, you could probably do something similar with dynamic size stuff such as ArrayLists but I can't test code now so that's the best I can come up with. – Juan Cortés Apr 27 '16 at 09:11
  • I tried your answer, but after that I have a problem to display the items in my listview, my adapter shows an error Error:(88, 91) error: incompatible types: CustomProduct[] cannot be converted to List EDIT: a predefined size is not a problem at all for me mate :) – Jay Apr 27 '16 at 09:30
  • Well, that's a totally different question.. You asked for a way to persist multiple objects into shared preferences, and I delivered a working (now tested) approach. Before using it in your adapter, create a list by iterating the array, or modify your adapter to take primitive arrays – Juan Cortés Apr 27 '16 at 09:32
  • Sorry I'm not great in Android, but I'm asking it because I need a visual result to see if it works.. example of a list iterating the array pls ? thank you Juan Cortes – Jay Apr 27 '16 at 09:40
  • 1
    Can you give me more details about your last comment please ? @Juan Cortés – Jay May 03 '16 at 08:38
  • 1
    This is the last I'm doing on this question, sorry but a question like this to which I've dedicated so much more time than usual, without zero reputation gained, without many views, it's basically doing consulting for free. Check the update, hope it's helpful – Juan Cortés May 03 '16 at 09:06
  • Thank you very much, I''m trying it as soon as I can... I will give you feedback, thanks Juan – Jay May 03 '16 at 09:21