开发者

Some help understanding columnIndex in ViewBInder

Skip to the bottom if you just want to see the question without context

The android app I'm building has a simple table with three columns:

_id INTEGER PRIMARY KEY..., name TEXT, color INT

This table is called categories. I load my categories from the database and feed them into a SimpleCursorAdapter for use with a Spinner like so:

String[] from = new String[] {
        ListDbAdapter.KEY_CATEGORY_NAME,
        ListDbAdapter.KEY_CATEGORY_COLOR };
int[] to = new int[] { R.id.categorySpinnerItem };

mCategorySpinnerAdapter = new SimpleCursorAdapter(this,
    R.layout.category_spinner_item, categoryCursor, from, to);

mCategorySpinnerAdapter
    .setViewBinder(new CategorySpinnerViewBinder());
mCategorySpinner.setAdapter(mCategorySpinnerAdapter);

I set a custom ViewBinder because I want the category name to be the text of the spinner item, and the color to be the background color. My ViewBinder looks like this:

private static final int NAME_COLUMN = 1;
private static final int COLOR_COLUMN = 2;

@Override
public boolean setViewValue(View view, Cursor cursor, int co开发者_高级运维lumnIndex) {

    TextView textView = (TextView) view;

    String name = cursor.getString(NAME_COLUMN);
    int color = cursor.getInt(COLOR_COLUMN);

    textView.setText(name);
    textView.setBackgroundColor(color);

    return true;
}

Here is my question (finally)

In the setViewValue method, what is columnIndex supposed to be doing? The documentation says "the column at which the data can be found in the cursor" but when I debug through setViewValue I hit it three times and columnIndex is always 1.

I was expecting the debugger to get into setViewValue once for each entry in the from array, with a columnIndex first of 1 and then 2. Or maybe once for each column in the query results.

The above code works, I can get the desired functionality but only because of my NAME_COLUMN and COLOR_COLUMN constants. I'd be really interested to hear an explanation of setViewValue and its parameters from someone more experienced with custom ViewBinders.


In the source of SimpleCursorAdapter, the setViewValue is called in bindView :

bound = binder.setViewValue(v, cursor, from[i]);

where the third param from[i], which is the interesting one, is an iteration over an int[], which represents the column indexes used. However the index for [i] for the iteration itself comes from the int[] to which is passed to the constructor of the adapter, and in your case, it has only 1 item - R.id.categorySpinnerItem

EDIT: In two words, the String[] and the int[] should be equivalent, same size and in same order - for each column name you need an int R.id... first view id will be connected to the first column id with from[0], second with from[1] and so on, and if you pass 10 columns, but you have only 3 R.id-s, you will get only to from[2] :)


I think that you are confused because you missed the part with the return value - true if you bind the data, false otherwise (and the adapter attempts to handle the binding on its own). I think that the idea is like with the OnTouchEvent- giving you the option to consume it or not. So, you are always returning true at index 1, and you are never offered the index 2, because you have binded the view already, that's the only explanation I can think of about having always only 1 in the columnIndex param.

However, I almost haven't used cursor adapters - I find them not-OO, it is way better to create a POJO somewhere else, initializing it however you want using the db columns, and when you have a shaped list of objects just sending them to a "normal" adapter, it sounds more MVC. For example, if at some point you decide that KEY_CATEGORY_NAME will be in the format "cat_name##cat_description" (for example) you have to change the Adapter. Sounds more reasonable to change your class Category, so the getName() will return just "cat_name", and the adapter is the same.

So, because I almost haven't used CursorAdapters , if I am right about the columnIndex, please DO tell me about it, because I am curious but I don't want to create a CursorAdapter and check it myself :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜