Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding views in a specific order and storing that order

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!

like image 255
John Sardinha Avatar asked Apr 29 '16 21:04

John Sardinha


People also ask

Can we add ORDER BY in view?

The ORDER BY clause is not valid in views, inline functions, derived tables, and subqueries, unless either the TOP or OFFSET and FETCH clauses are also specified. When ORDER BY is used in these objects, the clause is used only to determine the rows returned by the TOP clause or OFFSET and FETCH clauses.

Can views be stored?

Because views are stored as part of the database, they can be managed independently of the applications that use them. A view behaves like a virtual table. Since you can code a view name anywhere you can code a table name. a view is sometimes called a viewed table.

How do you set a specific order in SQL?

The ORDER BY statement in SQL is used to sort the fetched data in either ascending or descending according to one or more columns. By default ORDER BY sorts the data in ascending order. We can use the keyword DESC to sort the data in descending order and the keyword ASC to sort in ascending order.

Can we use ORDER BY to order a data set by several fields?

If you want to select records from a table but would like to see them sorted according to two columns, you can do so with ORDER BY . This clause comes at the end of your SQL query. After the ORDER BY keyword, add the name of the column by which you'd like to sort records first (in our example, salary).


3 Answers

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.

like image 181
kareem adel Avatar answered Nov 10 '22 00:11

kareem adel


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
}
like image 35
user Avatar answered Nov 10 '22 01:11

user


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.

like image 35
Jschools Avatar answered Nov 09 '22 23:11

Jschools