-4

Hi I am trying to allow the user to enter values which will be stored in a list. When the user exits that activity I want that list to be stored (IN THE SAME ORDER) to SharedPreferences and then once the user returns I want it to be displayed again in the correct order.

I have been advised to use a LinkedHashSet but it is still not maintaining the order.

I cant see where I am going wrong.

Here is my code attempt:

public class Processing extends AppCompatActivity {

TextView textView ;
Button  btnShippersCompleted, clear;
Handler handler;
ListView listView ;
String[] ListElements = new String[] {};
List<String> ListElementsArrayList ;
ArrayAdapter<String> adapter ;
String shippersCompleted;
int Hour;
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;

LinkedHashSet hs = new LinkedHashSet();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.processing);

    sharedPreferences = getSharedPreferences("MYPREFS", MODE_PRIVATE );
    editor = sharedPreferences.edit();

    textView = (TextView)findViewById(R.id.textView);
    btnShippersCompleted = (Button)findViewById(R.id.button4) ;
    listView = (ListView)findViewById(R.id.listview1);

    clear = (Button) findViewById(R.id.buttonClear);

    clear.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            editor.clear();
            editor.apply();
            listView.setAdapter(null);
        }
    });


    handler = new Handler() ;

    ListElementsArrayList = new ArrayList<String>(Arrays.asList(ListElements));

    adapter = new ArrayAdapter<String>(Processing.this,
            android.R.layout.simple_list_item_1,
            ListElementsArrayList
    );

    listView.setAdapter(adapter);

    btnShippersCompleted.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            shippersCompleted = textView.getText().toString();
            Hour = sharedPreferences.getInt("Hour", 1);
            ListElementsArrayList.add(shippersCompleted + " - Hour " + Hour++);
            hs.addAll(ListElementsArrayList);
            adapter.notifyDataSetChanged();
            listView.setAdapter(adapter);
            Intent intent = new Intent(getApplicationContext(), DataEntry_Primary.class);
            startActivity(intent);
            Toast.makeText(Processing.this, hs.toString(), Toast.LENGTH_LONG).show();

        }
    });

}

@Override
protected void onPause() {
    super.onPause();
    Set<String> set = new LinkedHashSet<>();
    set.addAll(ListElementsArrayList);
    editor.putStringSet("list", set);
    editor.putInt("Hour", Hour);
    editor.apply();
}
@Override
public void onResume() {
    super.onResume();
    Set<String> set = sharedPreferences.getStringSet("list", null);
    if(set != null) {
        ListElementsArrayList.addAll(set);
        listView.setAdapter(adapter);
    } else {
        Toast.makeText(Processing.this, "No records have been saved!",
                Toast.LENGTH_LONG).show();
    }

}

When I resume onto the activity again I am getting random orders like Hour 1, 3, 2, 5 , 4.

Can anyone help?

Edit attempt unsuccessful:

public void saveOrderedCollection(Collection collection, String key){
    JSONArray jsonArray = new JSONArray(collection);
    editor.putString(key, jsonArray.toString());
    editor.apply();
}

public Collection loadOrderedCollection(String key) throws JSONException {
    ArrayList arrayList = new ArrayList();
    JSONArray jsonArray = new JSONArray(sharedPreferences.getString(key, "[]"));
    for (int i = 0; i < jsonArray.length(); i++) {
        arrayList.add(jsonArray.get(i));
    }
    return arrayList;
}

@Override
protected void onPause() {
    super.onPause();
    saveOrderedCollection(ListElementsArrayList, String.valueOf(key));
}
@Override
public void onResume() {
    super.onResume();
    try {
        loadOrderedCollection(String.valueOf(key));
        listView.setAdapter(adapter);
    } catch (JSONException e) {
        e.printStackTrace();
    }

}
Aaron
  • 47
  • 11
  • Have you tried using a List instead of a Set? If so, why not a List? – DaGroove Jul 09 '18 at 13:23
  • also, you can always just sort your list – Dracarys Jul 09 '18 at 13:29
  • LinkedHashSet is not sorted LinkedHashSet is ordered based on insertion, give us a sample what do you expect and what is the actual result – Basil Battikhi Jul 09 '18 at 13:29
  • @BasilBattikhi.. see this post for what I am trying to achieve. I have been stuck on this for so long. https://stackoverflow.com/questions/51046473/saving-and-displaying-arraylist-in-correct-order – Aaron Jul 09 '18 at 13:42
  • i prefere to save the set as json in shared preference then you can retrieve the object from sharedpreference to linkedHashSet – Basil Battikhi Jul 09 '18 at 13:47
  • @DaGroove I was told to use a SET in order to be able to store it in sharedprefs. My code is so messy because I have been told so many suggestions. All that have not worked so far. – Aaron Jul 09 '18 at 13:51

1 Answers1

1

This is an issue with the way SharedPreferences works for your use case.

You're saving a LinkedHashSet with putStringSet but internally this is being converted to a HashSet:

    @Override
    public Editor putStringSet(String key, @Nullable Set<String> values) {
        synchronized (mEditorLock) {
            mModified.put(key,
                    (values == null) ? null : new HashSet<String>(values));
            return this;
        }
    }

(from https://github.com/aosp-mirror/platform_frameworks_base/blob/5edae415b08bd62eb50c7857a897173c4050983d/core/java/android/app/SharedPreferencesImpl.java#L400)

This answer covers a question with a similar issue and offers some possible solutions: https://stackoverflow.com/a/35567829/9995226

Sadiq
  • 61
  • 1
  • 2
  • I have tried using the answer from the post you tagged but it is still not working. I will update my post above with what I have tried – Aaron Jul 09 '18 at 13:48