1

I am using custom built content provider to pull data from my database. There can be many records(like 10k) so instead of implementing some mechanism of lazy loading to a list, I took a chance and created content-provider as it has internally a mechanism for "lazy loading". All works well. I need to add a field (column) which should not go in database, but it is a selector, a check-box. Say this is a list of some users loading from DB, and I want to create something close to WhatsApp "add contacts to broadcast" (see image)

adding contacts

The code for content provider is nothing special:

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    ................
        Cursor cursor = customContactsDataBase.getContacts(id, projection, selection, selectionArgs, sortOrder);
        return cursor;
    }

And getContacts is a simple SQLiteQueryBuilder returning a cursor.

So, my question is, should I inject this new check-box column, if yes, then where to keep the values (in a separate "matching by id" list or a map and dynamically fill the values) Or should I use some other mechanism ?

miroslavign
  • 2,033
  • 2
  • 24
  • 26
  • 2
    Most good implementation of "listview with check box" problem use SparseArray inside custom Adapter ... it is easy and there is a plenty tutorials out there – Selvin Feb 18 '16 at 14:27
  • 1
    see `ListView#getCheckedItemIds` and `ListView#getCheckedItemPositions` – pskink Feb 18 '16 at 17:05

1 Answers1

1

I've done something similar to this, a shopping list with favourites where you check the favourites to add them to your list.

I considered it a multi select context action bar (CAB), just forced permanently into the context action bar state. So I applied the same method I use for CABs.

In my adapter I add an array to hold checked items

private SparseBooleanArray checkedItems = new SparseBooleanArray();

I have public method in the adapter to toggle a check, get a list of all checked items and a few support methods as below.

public void toggleChecked(int pos) {
    Log.d(TAG, "Position " + pos);
    if (checkedItems.get(pos, false)) {
        checkedItems.delete(pos);
    } else {
        checkedItems.put(pos, true);
    }
    notifyItemChanged(pos);
}

public boolean isChecked(int pos) {
    return checkedItems.get(pos, false);
}

public void clearChecked() {
    checkedItems.clear();
    notifyDataSetChanged();
}

public int getCheckedItemCount() {
    return checkedItems.size();
}

public List<Integer> getCheckedItems() {
    List<Integer> items = new ArrayList<>(checkedItems.size());
    for (int i = 0; i < checkedItems.size(); i++) {
        items.add(checkedItems.keyAt(i));
    }
    return items;
}

You then just need to wire up your viewholder check event to go and update the adapter (I bubble the check event right up to the activity level then back into the adapter as I found it the easiest method with other validation required but that specific to my implementation).

CodeChimp
  • 4,745
  • 6
  • 45
  • 61
  • This looks so promising, shame on me for not thinking about at least a regular hash-map and pulling data beyond db scope and filling it into adapter. Will try this and then accept it. – miroslavign Feb 18 '16 at 18:21
  • 1
    @miroslavign this is all done in `AbsListView`: see `getCheckedItemIds` and `getCheckedItemPositions` methods, you can run the demo in ApiDemos `Views / Lists / 11. Multiple choice list`, source: [List11.java](https://github.com/appium/android-apidemos/blob/master/src/io/appium/android/apis/view/List11.java) – pskink Feb 18 '16 at 18:38
  • 1
    @pskink is right for listviews, they have a lot more built in. I was basing my answer on you using a recyclerview where you have to do all the work yourself though with more flexibility. – CodeChimp Feb 18 '16 at 18:46
  • 1
    I marked this one as it provided a solution for my needs. And, yes it's easier if you have only a ListView to use embedded AbsListView(which is in my case = ListView+ContentProvider). @pskink tnx for pointer though – miroslavign Feb 21 '16 at 13:42