I tried the solution provided by @naktinis, but the result wasn't what I expected. What I myself wanted to achieve as an adapter in which new elements can be added at the top (index 0). However, with the solution given, new elements were indeed added at the top but only to the END of the MatrixCursor. In other words, when I added rows dynamically to the "extras" MatrixCursor, I got something like this:
- "extras" row 1
- "extras" row 2
- "extras" row 3
- "cursor" row 1
- "cursor" row 2
- "cursor" row 3.
However, what I really wanted to achieve was something like this:
- "extras" row 3
- "extras" row 2
- "extras" row 1
- "cursor" row 1
- "cursor" row 2
- "cursor" row 3.
In other words, most recent elements enter at the top (index 0).
I was able to achieve this manually by doing the follow. Note that I did not include any logic to handle dynamically removing elements from the adapter.
private class CollectionAdapter extends ArrayAdapter<String> {
/**
* This is the position which getItem uses to decide whether to fetch data from the
* DB cursor or directly from the Adapter's underlying array. Specifically, any item
* at a position lower than this offset has been added to the top of the adapter
* dynamically.
*/
private int mCursorOffset;
/**
* This is a SQLite cursor returned by a call to db.query(...).
*/
private Cursor mCursor;
/**
* This stores the initial result returned by cursor.getCount().
*/
private int mCachedCursorCount;
public Adapter(Context context, Cursor cursor) {
super(context, R.layout.collection_item);
mCursor = cursor;
mCursorOffset = 0;
mCachedCursorCount = -1;
}
public void add(String item) {
insert(item, 0);
mCursorOffset = mCursorOffset + 1;
notifyDataSetChanged();
}
@Override
public String getItem(int position) {
// return the item directly from underlying array if it was added dynamically.
if (position < mCursorOffset) {
return super.getItem(position);
}
// try to load a row from the cursor.
if (!mCursor.moveToPosition(position - mCursorOffset)) {
Log.d(TAG, "Failed to move cursor to position " + (position - mCursorOffset));
return null; // this shouldn't happen.
}
return mCursor.getString(INDEX_COLLECTION_DATA);
}
@Override
public int getCount() {
if (mCachedCursorCount == -1) {
mCachedCursorCount = mCursor.getCount();
}
return mCursorOffset + mCachedCursorCount;
}
}