Reputation: 3423
I have an 'add' button and a GridLayout with 6 slots in it, when I click the 'add' button, view1 gets added into the gridlayout, I click the 'add' button again view2 gets added, and so on.
if (!theLayout1.isShown()) {
Grid.addView(theLayout1);
} else if (!theLayout2.isShown()) {
Grid.addView(theLayout2);
} else if (!theLayout3.isShown() ) {
Grid.addView(theLayout3);
} ..... // this goes on
after a view gets added I check if its text was already added into sharedPrefs so they can be automatically added when reCreating the activity
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, if I remove view1 and then add it again, it will be placed in the last slot as I want it to, but when I recreate the activity it will go back to first place, because since the code gets read in its order it will add the views in their initial order.
I want to add the views when recreating the activity in the order they were before finishing the activity, this may have a simple logical solution or maybe I'm just approaching the problem very wrongly, in any case, help is needed!
Upvotes: 8
Views: 408
Reputation: 491
First of all you could store the views tags "or whatever you mark them with" in a data structure that has a tag and the position that the view is in, then store 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 mentioned above, you could sort the results based on their 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 dataStructure and add the views to the GridLayout in order normally.
Upvotes: 2
Reputation: 5236
I would handle Such a thing by Using JsonArray
Whenever you add a view, add that text in the json array, and then store it in your shared preference as a string.
jsonarray.toString()
You can easily add and remove items as your views get removed or added. Also this help you to have just one shared preference and prevent working with different shared preferences.
SharedPreferences sf = .....
String txt=sf.getString("YOUR_KEY","");
JsonArray myViewArray=new JsonArray(txt);
for(int i=0;i<myViewArray.length();i++){
// ADD VIEW HERE
}
Upvotes: 1
Reputation: 2758
This boils down to inserting items into a sorted array. There is a method addView(View child, int index)
that will add the view at the desired position, which is what you want to use. You'll need to iterate over the currently added children and find the correct index at which to insert the new one. If you tag each view with its value before you add it, you can look at the tags to determine where this index is.
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's 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 views are always in the correct order. It could be optimized futher by implementing a binary search, but if you have that many Views you should use a ListView anyways.
However, you may want to reconsider this architecture altogether, since you have a lot of redundant code that may be simplified with a loop or data structure. Alternatively, you could always add all the views, and just call theLayout.setVisibility(View.GONE)
when you want to hide one and theLayout.setVisibility(View.VISIBLE)
when you want to show it.
Upvotes: 1
Reputation: 3774
you should store the name the name of your layout + a counter . ex : Layout1, layout2, layout3...
When you want to get them in the order, you just need to loop until you don't have anything to retrieve :
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 it helps !
Upvotes: 0
Reputation: 87064
The problem(at least from what I understood from your question) is that you don't save in the preferences some sort of indicator for the position of the view in its parent. Right now there's no difference between adding for the first time vs adding the view again after deleting it, or between adding the view at slot 1 vs slot 5(for example). One way to handle this would be to have an entry in preferences for each of those slots and then save in those slot preferences the view indicator:
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's 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's 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'll recreate the activity look at all the SLOT preferences and see which values they hold. They could be null if your layout allows having holes(like not having a view for slot 2, but having a view for slot 1 and 3) or they could hold one of your text* variables indicating which view should be placed in that 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
}
Upvotes: 1