мой вопрос в том, как получить доступ и изменить режим checkBox для любого элемента в списке. У меня есть файл шаблона XML с флажком и текстовым окном, и они определяют строку. Вот то, что я пытаюсь сделать до сих пор:
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(this, "You selected: " + Integer.toString(position), Toast.LENGTH_LONG).show();
CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox);
if (checkbox.isChecked() == false) {
checkbox.setChecked(true);
} else {
checkbox.setChecked(false);
}
}
Очевидно, хотя использование R.id.checkbox только переключает первый флажок (фактически, он делает первый флажок любой части списка, который я просматриваю на своем экране). Я не уверен, какую функцию использовать, чтобы получить флажок любой строки. Тост отлично работает, так что, по крайней мере, он правильно регистрирует позицию.
Спасибо за любую помощь.
EDIT - теперь я пытаюсь подклассифицировать SimpleCursorAdapter, чтобы лучше контролировать поведение, которое я хочу. Вот этот подкласс:
public class musicPlaylist extends SimpleCursorAdapter {
private Cursor c;
private Context context;
private ArrayList<String> checkList = new ArrayList<String>();
private final static int SELECTED = 1;
private final static int NOT_SELECTED = 0;
public musicPlaylist(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.song_item, null);
}
this.c.moveToPosition(pos);
int columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
String song = this.c.getString(columnIndex);
TextView sTitle = (TextView) v.findViewById(R.id.text1);
sTitle.setText(song);
v.setId(NOT_SELECTED);
v.setTag(song);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId() == NOT_SELECTED) {
v.setId(SELECTED);
Toast.makeText(context, "Test: " + v.getId(), Toast.LENGTH_SHORT).show();
v.setBackgroundColor(Color.parseColor("#FFFFFF"));
} else {
v.setId(NOT_SELECTED);
Toast.makeText(context, "Test: " + v.getId(), Toast.LENGTH_SHORT).show();
v.setBackgroundColor(Color.parseColor("#000000"));
}
}
});
return v;
}
}
И для справки, вот XML ListActivity, который я делаю:
<?xml version="1.0" encoding="utf-8"?>
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"
android:fastScrollEnabled="true"
android:cacheColorHint="#00000000"
/>
<TextView android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="No data"/>
Текущее поведение: список песен с SD-карты превращается в список с прокручиваемым списком. Я получаю несколько правильные ответы от getView() onClick: при первом щелчке элемента он тосты, что его тег "1", а его фон белеет, а во второй раз, когда я тост одного и того же элемента, я получаю "0", и фон становится черным, что и ожидалось.
Проблема в том, что если я выберу item1 (сделав его белым фоном), а затем прокрутите вниз, я увижу, что item11, item21, item31,... и т.д. Также имеют белый фон. Но когда я нажимаю на них, их идентификатор атрибута переходит в "1", что означает, что они никогда не были нажаты до этого! Итак, в основном, когда свиток "обновляется" до следующего списка из 10, он копирует цветовую схему первых 10...?
Надеюсь, я объяснил это четко.
Я думаю, что это более глубокий вопрос, и не нужен прямой ответ.
Чего вы хотите достичь? Вы действительно хотите сделать выбранным ТОЛЬКО флажками, которые вы видите на экране? Помните, что это может быть довольно случайным - просмотр списка содержит только представления элементов для флажков, которые видны на экране, и они используются повторно для других элементов всякий раз, когда элемент прокручивается за пределы экрана.
Я бы сказал, что почти наверняка вам нужно изменить состояние всех флажков в вашем списке (даже те, которые не видны) или некоторые подмножества из них (например, раздел). Что действительно переводится правильно, это должно быть сделано:
В результате, представление списка воссоздает все виды, которые видны на экране. Предполагая, что ваш "getView()" в адаптере написан правильно, он правильно прочитает правильную модель и обновит состояние проверки на элементе. By notifyDataSetChanged - если у вас есть 10 элементов, видимых на экране, у вас будет 10 раз getView() для каждого видимого элемента.
Я рекомендую использовать android:choiceMode="multipleChoice"
вместо того, чтобы вручную манипулировать вашими строками таким образом. Виджет строки должен будет реализовать интерфейс Checkable
, который может быть выполнен с помощью CheckedTextView
качестве самой строки или создания подкласса вашего желаемого контейнера и реализации Checkable
на нем.
Вместо этого вы видите "глобальный" вид. Попробуйте вот так:
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
CheckBox checkbox = (CheckBox) v.findViewById(R.id.checkbox);
if (checkbox.isChecked() == false) {
checkbox.setChecked(true);
} else {
checkbox.setChecked(false);
}
}