按特定顺序添加视图并存储该顺序

我有一个“添加”button和一个带有6个插槽的GridLayout,当我点击“添加”button,view1被添加到网格布局,我再次点击“添加”button,view2被添加,等等。

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

添加视图后,我检查它的文本是否已经添加到sharedPrefs中,以便在重新创build活动时自动添加

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

我的问题是,如果我删除view1,然后再次添加,它将被放置在最后一个插槽,因为我想要它,但是当我重新创build活动它会回到第一位,因为代码被读取其中为了它将按照他们的初始顺序添加视图。

我想在完成活动之前按顺序重新创build活动时添加视图,这可能有一个简单的逻辑解决scheme,或者我只是非常错误地接近问题,无论如何,需要帮助!

Solutions Collecting From Web of "按特定顺序添加视图并存储该顺序"

首先,您可以将视图标签或其标记的视图标签存储在具有标签和视图位置的数据结构中,然后将代码存储在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(); } } 

然后,当您检索上面提到的数据结构时,您可以使用以下代码根据其位置对结果进行sorting:

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

然后迭代dataStructure中的sorting结果,并按顺序将视图添加到GridLayout。

这个问题(至less从我的问题中可以理解的)是,你不会在喜好中保存视图在父类中位置的某种指示器。 现在,第一次添加和删除之后再添加视图,或者在第1个插槽和第5个插槽之间添加视图(例如)之间没有区别。 处理这种情况的一种方法是在每个这些插槽中input一个首选项,然后在这些插槽首选项中保存视图指示器:

例如:

 // 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 

当您重新创build活动时,请查看所有SLOT首选项并查看它们所持有的值。 如果你的布局允许有孔(比​​如没有插槽2的视图,但是有插槽1和3的视图),或者他们可以保存你的文本*variables中的一个来指示哪个视图应该放置在那个插槽中,它们可以为null:

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

这归结为插入项目到一个sorting的数组。 有一个方法addView(View child, int index) ,将添加视图在所需的位置,这是你想要使用的。 您需要迭代当前添加的子项并find插入新子项的正确索引。 如果您在添加之前使用其值来标记每个视图,则可以查看标记以确定该索引的位置。

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

然后,当你需要插入一个布局时,你可以这样做:

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

这应该确保你的观点总是以正确的顺序。 它可以通过实现二进制search进一步优化,但如果你有这么多的视图,你应该使用ListView反正。

但是,您可能希望完全重新考虑这个架构,因为您有很多冗余代码,可以使用循环或数据结构进行简化。 或者,您可以随时添加所有视图,只要在要显示theLayout.setVisibility(View.VISIBLE)时隐藏一个和theLayout.setVisibility(View.VISIBLE) ,就调用theLayout.setVisibility(View.GONE)

我会通过使用JsonArray处理这样的事情

每当你添加一个视图,在json数组中添加这个文本,然后把它作为一个string存储在你的共享首选项中。

 jsonarray.toString() 

随着视图被移除或添加,您可以轻松添加和移除项目。 此外,这可以帮助您只有一个共享首选项,并防止使用不同的共享首选项。

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

你应该存储你的布局名称+计数器名称。 例如:Layout1,layout2,layout3 …

当你想让他们顺序,你只需要循环,直到你没有任何检索:

  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 

希望能帮助到你 !