Sorting RadioButtons: The Magic Star ‘★’

The Magic Star ‘★’: insight into how the issue of sorting RadioButtons according to frequency of use was solved in the multi courier app

The Multi Courier Tracker app uses two vertical RadioGroups, with lots of RadioButtons in each, for selecting which courier to track.
Magic Star
Once the number of couriers gradually increased to 50, the question arose how to give an option to bring the more frequently required / used ones to the top.

The simplest solution was to dispense with the RadioButtons and go for a ListView. But there was something nice about the RadioButtons!

How it was done, retaining the RadioButtons:

  1. First, removed all the RadioButtons from the XML layout
  2. Instead, made an array of RadioButtons in code, and also an array of ids, with one integer id for each courier. The names and colors for each courier button was mapped against its id, in two SparseIntArrays.
  3. In the onCreate() Method, looped through the id array to create each RadioButton, and add it to the RB array. Each RadioButton was also mapped to its id, in a global SparseArray.
    int index = 0;
    for (int crid:idarray) {
    RadioButton rbinst = new RadioButton(this);
    //name - Points to a String resource
    int name = nameMap.get(crid);
    int color = colorMaps.get(crid);
    rbinst.setText(name);
    rbinst.setTextColor(color);
    //The Key Step: The id of each RB is set here
    rbinst.setId(crid);
    rbArray[index++]=rbinst;
    //Global SparseArray mapping each RB to an id
    cridMap.put(crid, rbinst);
    }
  4. The RadioButtons are then added one-by-one to the layout in the onStart() method using a loop and a flag variable to put them into one of the two Radiogroups in tandem:
    boolean odd=true;
    for (int id : idarray) {
    (odd ? rgCR1 : rgCR2).addView(cridMap.get(id));
    odd = !odd;
    }
  5. When the user tracks a courier, the counter for that courier is incremented and stored in a SharedPreference integer value, with the key as the courier id + “_COUNT”
    String COUNT_KEY = CRID+"_COUNT";
    int crcount = sharedpref.getInt(COUNT_KEY, 0);
    crcount++;
    sharedpref.edit().putInt(COUNT_KEY,crcount).commit();
  6. Each time the activity starts,   the courier tracking counts are retrieved, again in a loop, and mapped to each courier id in a SparseIntArray. The counts are also separately added to an Array, which is then sorted using Arrays.sort(array). The id against each track count is then retrieved in descending order and stored in another array the sorted id array.
    Here is the full method:
    void sortRbs() {
    SparseIntArray crcounts = new SparseIntArray(idarray.length);
    int[] track_counts = new int[idarray.length];
    int index = 0;
    for (int crid:idarray) {
    int crcount = sharedpref.getInt(crid+"_COUNT", 0);
    counts[index++] = crcount;
    crcounts.put(crid, crcount);
    }
    //The Powerhouse: One-line sorting step
    Arrays.sort(track_counts);
    ArrayList cridtemp = new ArrayList(crids.length);
    for (int crid : idarray) {
    cridtemp.add(crid);
    }
    index = 0;
    //Descending loop
    for (int i=track_counts.length-1;i>-1;i--) {
    int removedindex = 0;
    for (int j=0;j<cridtemp.size(); j++) {
    int crid = cridtemp.get(j);
    if (crcounts.get(crid)==track_counts[i]){
    //sorted_crids is the global array variable that will hold the sorted ids
    sorted_crids[index++]=crid;
    removedindex = j;
    break;
    }}
    cridtemp.remove(removedindex);
    }}
  7. A button which toggles its title between the unicode characters ☆ & ★ was added to the view. When clicked, a boolean sort variable is set/unset. The RadioButtons are removed from the RadioGroups and added back.  Depending on the state of the boolean sort variable, the sorted or unsorted id arrays are used to order the added RadioButtons – and thereby achieving the desired result.

 

Get it on Google Play

A Regular Expression to match all HTML tags

Sharing a Regular Expression to match all HTML tags along with the surrounding white space.

A regular expression to match all HTML tags, including surrounding white space, as well as clustered tags:

/(\s*<[^>]+>\s*)+/

For example,  this can be used in java (or android) code to split an HTML table and return the contained text in each cell as members of an array of strings :

 String tablecontents [] = htmltable.split("(\\s*<[^>]+>\\s*)+");

This uses the string splitter function String.split(regexp) which can split strings based on a given regular expression.  The fragments are returned as an array, which is quite handy.