Android: привязка данных из базы данных к CheckBox в ListView?
Я пытаюсь связать данные с моего SQLiteDatabase
с ListView
. В настоящее время я использую SimpleCursorAdapter
для заполнения моего ListView
. К сожалению, это не работает с установкой атрибута CheckBox checked.
Вот как я это делаю сейчас; вместо изменения контрольного состояния CheckBox адаптер заполняет значение текстовому аргументу, поэтому значение отображается справа от CheckBox как текст.
Java:
setListAdapter( new SimpleCursorAdapter( this,
R.layout.mylist,
data,
new String[] { Datenbank.DB_STATE, Datenbank.DB_NAME },
new int[] { R.id.list_checkbox, R.id.list_text }
) );
mylist.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<CheckBox android:text=""
android:id="@+id/list_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
></CheckBox>
<TextView android:text=""
android:id="@+id/list_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView>
</LinearLayout>
Изменить: поле в базе данных, конечно, имеет тип boolean, и я также попытался присвоить идентификатор проверяемому полю, чтобы заполнить значение.
Ответы
Ответ 1
Я не уверен, как вы это сделаете, помимо создания настраиваемого адаптера, который перекроет newView/bindView или getView, в зависимости от того, что вы переопределите (ResourceCursorAdapter является хорошим).
Итак, вот пример. Я не проверял, будет ли он компилироваться, потому что я на работе, но это обязательно должно указывать вам в правильном направлении:
public class MyActivity extends ListActivity {
MyAdapter mListAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor myCur = null;
myCur = do_stuff_here_to_obtain_a_cursor_of_query_results();
mListAdapter = new MyAdapter(MyActivity.this, myCur);
setListAdapter(mListAdapter);
}
private class MyAdapter extends ResourceCursorAdapter {
public MyAdapter(Context context, Cursor cur) {
super(context, R.layout.mylist, cur);
}
@Override
public View newView(Context context, Cursor cur, ViewGroup parent) {
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return li.inflate(R.layout.mylist, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cur) {
TextView tvListText = (TextView)view.findViewById(R.id.list_text);
CheckBox cbListCheck = (CheckBox)view.findViewById(R.id.list_checkbox);
tvListText.setText(cur.getString(cur.getColumnIndex(Datenbank.DB_NAME)));
cbListCheck.setChecked((cur.getInt(cur.getColumnIndex(Datenbank.DB_STATE))==0? false:true))));
}
}
}
Ответ 2
Вы можете установить пользовательский SimpleCursorAdapter.ViewBinder
:
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(/* ur stuff */);
cursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(columnIndex == 1) {
CheckBox cb = (CheckBox) view;
cb.setChecked(cursor.getInt(1) > 0);
return true;
}
return false;
}
});
Метод setViewValue
вызывается для каждого столбца, заданного в конструкторе SimpleCursorAdapter
, и дает вам хорошее место для манипулирования некоторыми (или всеми) представлениями.
Ответ 3
Вы можете решить эту проблему, создав собственный виджет CheckBox следующим образом:
package com.example.CustomCheckBox;
public class CustomCheckBox extends CheckBox {
public CustomCheckBox(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomCheckBox(Context context) {
super(context);
}
protected void onTextChanged(CharSequence text, int start, int before, int after) {
if (text.toString().compareTo("") != 0) {
setChecked(text.toString().compareTo("1") == 0 ? true : false);
setText("");
}
}
}
Функция onTextChanged будет вызываться, когда ListView связывает данные с CheckBox (т.е. добавляет либо "0", либо "1" ). Это заставит это изменение и добавит в вашу логическую обработку. 1-й оператор "if" необходим, чтобы не создавать бесконечную рекурсию.
Затем укажите свой собственный класс в файл макета как таковой:
<com.example.CustomCheckBox
android:id="@+id/rowCheckBox"
android:layout_height="fill_parent"
android:layout_width="wrap_content" />
Это должно сделать это!