Adding views in a specific order and maintaining that order

I have an add button and a GridLayout with 6 slots in it, when I click the add button, view1 is added to the gridlayout, I click the add button, view2 appears again, etc.

if (!theLayout1.isShown()) { Grid.addView(theLayout1); } else if (!theLayout2.isShown()) { Grid.addView(theLayout2); } else if (!theLayout3.isShown() ) { Grid.addView(theLayout3); } ..... // this goes on 

after adding the view. I check if its text has already been added to sharedPrefs so that they can be automatically added when the action is recreated.

 if (prefs.getString("text4", null) != null) { Grid.addView(theLayout4); } if (prefs.getString("text5", null) != null) { Grid.addView(theLayout5); } // each view has one EditText 

My problem is that if I delete view1 and then add it again, it will be placed in the last slot as I want it, but when I recreate the action, it will return to first place, because since the code gets read in in his order, he will add the submission in their original order.

I want to add representations when I recreate the activity in the order in which they were before the operation was completed, this may have a simple logical solution, or maybe I just very poorly approach this problem, in any case I need help!

+8
java android android-layout logic
source share
5 answers

First of all, you can store the presentation tags "or whatever you label them" in the data structure containing the tag and the position in which the view is located, and then save the code in SharedPreferences.

 public void savePreferences() { SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); SharedPreferences.Editor prefsEditor = mPrefs.edit(); Gson gson = new Gson(); String json = gson.toJson(dataStructure, new TypeToken<DataStructure>() { }.getType()); prefsEditor.putString("ordering", json); prefsEditor.commit(); } public static DataStructure loadPreferences() { SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); Gson gson = new Gson(); String json = mPrefs.getString("ordering", ""); if (!json.equals("")) { return (DataStructure) gson.fromJson(json, new TypeToken<DataStructure>() { }.getType()); } else { return new DataStructure(); } } 

Then, when you retrieve the data structure as described above, you can sort the results based on your positions using the following code:

 Arrays.sort(dataStructure , new Comparator<DataStructureElement>() { @Override public int compare(DataStructureElement o1, DataStructureElement o2) { return Integer.compare(o1.position, o2.position); } }); 

Then iterate over the sorted results in a dataStructure and add the views to the GridLayout in the order as usual.

+2
source share

The problem (at least from what I understood from your question) is that you do not save some indicator in the settings for the presentation position in your parent. Right now there is no difference between adding the first time and adding the view again after deleting it or between adding the view to slot 1 and slot 5 (for example). One way to deal with this would be to have an entry in the settings for each of these slots, and then save a view indicator in these settings of the slot:

For example:

 // the base of the slot keys, there will be 6 of them from 1 to 6 inclusive private static final String KEY_SLOT = "key_slot"; // when adding the view for slot 2 you'll save in preferences text2 it indicator prefEditor.putString(KEY_SLOT + position, text2); // position will be 2, the indicator of the slot in your layout // when you delete the view from a slot, nullify it slot preferences // for example deleting the slot 3(child 3 in the layout) prefEditor.putString(KEY_SLOT + position, null); position will be 3 

When you recreate the activity, look at all the SLOT settings and see what values ​​they store. They can be null if your layout allows you to have holes (for example, not to have a view for slot 2, but to have a view for slot 1 and 3), or they may contain one of your text * variables indicating which view should be placed in this slot:

 // in the activity: // iterate over all the SLOT preferences for (int i = 1; i <= 6; i++) { String text = prefs.getString(KEY_SLOT + i, null); // if text is null there is no view stored for this slot // keep in mind that you need to add some sort of empty widget to act as a child // or modify the LayoutParams of the other children to take in consideration the empty space // OR // if text is one of your values, like text1, text2 etc // then you know that at slot i you need to place the view corresponding to the text value } 
+1
source share

It comes down to inserting elements into a sorted array. There is an addView(View child, int index) method that will add the view to the desired position that you want to use. You will need to iterate over all the added children and find the correct index into which you need to insert a new one. If you tag each view with its own value before adding it, you can look at the tags to determine where the index is located.

 private void insertView(View theLayoutN, int n) { // tag the new view with its value theLayoutN.setTag(Integer.valueOf(n)); // iterate over the views currently in the grid, keeping track // of the desired insertion index int insertionIndex = 0; final int childCount = grid.getChildCount(); for (int i = 0; i < childCount; i++) { // get the child currently at index i View child = grid.getChildAt(i); // retrieve its tag, which is its value int childN = ((Integer) child.getTag()).intValue(); // if the child value is greater than the value of the // one we're inserting, then we have found the insertionIndex if (childN > n) { break; } // increment the insertionIndex insertionIndex++; } grid.addView(theLayoutN, insertionIndex); } 

Then, when you need to insert a layout, you can do this:

 if (!theLayout1.isShown()) { insertView(theLayout1, 1); } else if (!theLayout2.isShown()) { insertView(theLayout2, 2); } else if (!theLayout3.isShown()) { insertView(theLayout3, 3); } 

This should ensure that your submissions are always in the correct order. It could be optimized by implementing a binary search, but if you have many views, you should use a ListView anyway.

However, you may need to completely rethink this architecture as you have a lot of redundant code that can be simplified with a loop or data structure. In addition, you can always add all the views and simply call theLayout.setVisibility(View.GONE) if you want to hide one and theLayout.setVisibility(View.VISIBLE) when you want to show it.

+1
source share

I would handle such a task using JsonArray

Whenever you add a view, add that text to the json array, and then save it in your general preference as a string.

 jsonarray.toString() 

You can easily add and remove items as you delete or add your views. In addition, it will help you to have only one shared preference and not work with different settings.

 SharedPreferences sf = ..... String txt=sf.getString("YOUR_KEY",""); JsonArray myViewArray=new JsonArray(txt); for(int i=0;i<myViewArray.length();i++){ // ADD VIEW HERE } 
+1
source share

You must save the name of your layout name + counter. ex: Layout1, layout2, layout3 ...

When you want to get them in order, you just need to go in cycles until you have nothing to extract:

  int i = 1; String valueStored = null; do { String key = "layout" + i; // layout1, layout2, layout3... SharedPreferences preferences = activity.getSharedPreferences(key, 0); valueStored = preferences.getString(key, null); // View v = getViewByName(valueStored) get the view by the name retrieved from the shared pref //Grid.addView(view); } while (valueStored != null); // stop when there is nothing more to get 

Hope this helps!

0
source share

All Articles