Некоторая помощь в понимании columnIndex во ViewBInder
Перейдите к нижней части, если вы просто хотите увидеть вопрос без контекста
Приложение Android, которое я создаю, имеет простую таблицу с тремя столбцами:
_id INTEGER PRIMARY KEY..., имя TEXT, цвет INT
Эта таблица называется categories
, Я загружаю свои категории из базы данных и подаю их в SimpleCursorAdapter
для использования с Spinner
вот так:
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);
Я поставил кастом ViewBinder
потому что я хочу, чтобы имя категории было текстом элемента счетчика, а цвет - цветом фона. мой ViewBinder
выглядит так:
private static final int NAME_COLUMN = 1;
private static final int COLOR_COLUMN = 2;
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
TextView textView = (TextView) view;
String name = cursor.getString(NAME_COLUMN);
int color = cursor.getInt(COLOR_COLUMN);
textView.setText(name);
textView.setBackgroundColor(color);
return true;
}
Вот мой вопрос (наконец-то)
В методе setViewValue, что должен делать columnIndex? В документации написано "столбец, в котором можно найти данные в курсоре", но когда я отлаживаю через setViewValue, я нажимаю на него три раза, а columnIndex всегда 1
,
Я ожидал, что отладчик попадет в setViewValue один раз для каждой записи в массиве from, а columnIndex будет первым из 1
а потом 2
, Или, может быть, один раз для каждого столбца в результатах запроса.
Приведенный выше код работает, я могу получить желаемую функциональность, но только из-за моих констант NAME_COLUMN и COLOR_COLUMN. Мне было бы действительно интересно услышать объяснение setViewValue и его параметров от кого-то более опытного с пользовательскими ViewBinders.
2 ответа
В источнике SimpleCursorAdapter, setViewValue
называется в bindView
:
bound = binder.setViewValue(v, cursor, from[i]);
где третий параметр из [i], который является интересным, представляет собой итерацию над int [], который представляет используемые индексы столбцов. Однако индекс для [i] для самой итерации берется из int [], которому передается конструктор адаптера, и в вашем случае он имеет только 1 элемент - R.id.categorySpinnerItem
РЕДАКТИРОВАТЬ: в двух словах String[] и int [] должны быть эквивалентны, одинакового размера и в том же порядке - для каждого имени столбца вам нужен int R.id... идентификатор первого вида будет связан с первым столбцом id с from[0], второй с from[1] и так далее, и если вы пропустите 10 столбцов, но у вас есть только 3 R.id-s, вы получите только к из [2]:)
Я думаю, что вы запутались, потому что вы пропустили часть с возвращаемым значением - true, если вы связываете данные, иначе false (и адаптер пытается обработать привязку самостоятельно). Я думаю, что идея похожа на OnTouchEvent
- давая вам возможность потреблять его или нет. Таким образом, вы всегда возвращаете true в индексе 1, и вам никогда не предлагается индекс 2, потому что вы уже связали представление, это единственное объяснение, которое я могу придумать, чтобы всегда иметь только 1 в столбце columnIndex.
Тем не менее, я почти не использовал адаптеры курсора - я нахожу их не-OO, лучше создать POJO где-то еще, инициализировать его так, как вы хотите, используя столбцы db, и когда у вас есть сформированный список объектов, просто отправляющий их к "нормальному" адаптеру, это звучит больше MVC. Например, если в какой-то момент вы решите, что KEY_CATEGORY_NAME
будет в формате "cat_name##cat_description" (например), вы должны изменить Adapter
, Кажется более разумным изменить категорию вашего класса, поэтому getName() вернет просто "имя_каталога", а адаптер тот же.
Итак, потому что я почти не использовал CursorAdapters
, если я прав насчет columnIndex, пожалуйста, Скажите мне об этом, потому что мне любопытно, но я не хочу создавать CursorAdapter и проверять его сам:)