Android save Checkbox State in ListView with Cursor Adapter
I would recommend you use Android's built-in support for multiple-choice lists (CHOICE_MODE_MULTIPLE
).
The List11.java
SDK sample demonstrates this. You can also find a project from one of my tutorials that uses it here.
You can still use this technique with your own layout, so long as you include a CheckedTextView
with android:id="@android:id/text1"
as shown in the android.R.layout.simple_list_item_multiple_choice
resource, a copy of which ships with your SDK.
Also, see this question and this question and this question and this question.
Android: CursorAdapter, ListView and CheckBox
There are a few concerns with the ListView when having checkable items in it. I would suggest the following link:
http://tokudu.com/2010/android-checkable-linear-layout/
I think it's close to what you want.
Maintaining checkbox states in listview with CursorAdapter
Reason : ListView re-uses the views.
Solution :
class VocabCursorAdapter extends CursorAdapter {
List<Integer> selectedItemsPositions;//to store all selected items position
public VocabCursorAdapter(Context context, Cursor c,int flags) {
super(context, c,0);
selectedItemsPositions = new ArrayList<>();
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
View view = LayoutInflater.from(context).inflate(R.layout.item_vocab, viewGroup, false);
CheckBox box = (CheckBox) view.findViewById(R.id.editCheckbox);
box.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int position = (int) compoundButton.getTag();
if (b) {
//check whether its already selected or not
if (!selectedItemsPositions.contains(position))
selectedItemsPositions.add(position);
} else {
//remove position if unchecked checked item
selectedItemsPositions.remove((Object) position);
}
}
});
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
//your other stuff
CheckBox box = (CheckBox) view.findViewById(R.id.editCheckbox);
box.setTag(cursor.getPosition());
if (selectedItemsPositions.contains(cursor.getPosition()))
box.setChecked(true);
else
box.setChecked(false);
}
}
CursorAdapter in Listview
problem is when you update your database just database going to update not cursor that adapt your cursor adapter ,so you have to use
changeCursor(newcursor);
in your adapter after updating your database.
hope this help you.
Storing CheckBox state in a ListView
You question didn't say anything about storing the data after the application has closed. To store the checked CheckBoxes
you could use a database or a simple file. Bellow is an example of storing the CheckBox
state in a database:
public class SimplePlay extends ListActivity {
private String[] soundnames;
private Helper mHelper = new Helper(this, "position_status.db", null, 1);
private SQLiteDatabase statusDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this is to simulate data
soundnames = new String[40];
for (int i = 0; i < 40; i++) {
soundnames[i] = "Sound " + i;
}
// Retrieve the list of position that are checked(if any) from the
// database
statusDb = mHelper.getWritableDatabase();
Cursor statusCursor = statusDb.rawQuery("SELECT * FROM status", null);
int[] savedStatus = null;
if ((statusCursor != null) & (statusCursor.moveToFirst())) {
savedStatus = new int[statusCursor.getCount()];
int i = 0;
do {
savedStatus[i] = statusCursor.getInt(0);
i++;
} while (statusCursor.moveToNext());
}
// if the cursor is null or empty we just pass the null savedStatus to
// the adapter constructor and let it handle(setting all the CheckBoxes
// to unchecked)
setListAdapter(new MobileArrayAdapter(this, soundnames, savedStatus));
}
public class MobileArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
public MobileArrayAdapter(Context context, String[] values,
int[] oldStatus) {
super(context, R.layout.adapters_simpleplay_row, values);
this.context = context;
this.values = values;
// make every CheckBox unchecked and then loop through oldStatus(if
// not null)
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false);
}
if (oldStatus != null) {
for (int j = 0; j < oldStatus.length; j++) {
itemChecked.set(oldStatus[j], true);
}
}
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.adapters_simpleplay_row,
parent, false);
}
CheckBox cBox = (CheckBox) rowView.findViewById(R.id.checkBox1);
cBox.setTextColor(0xFFFFFFFF);
cBox.setText(values[position]);
cBox.setTag(new Integer(position));
cBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
int realPosition = (Integer) buttonView.getTag();
if (isChecked) {
itemChecked.set(realPosition, true);
// update the database to store the new checked item:
ContentValues cv = new ContentValues();
cv.put("list_position", realPosition);
statusDb.insert("status", null, cv);
} else {
itemChecked.set(realPosition, false);
// delete this position from the database because it was
// unchecked
statusDb.delete("status", "list_position = "
+ realPosition, null);
}
}
});
cBox.setChecked(itemChecked.get(position));
return rowView;
}
}
//for working with the database
private class Helper extends SQLiteOpenHelper {
public Helper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// the list_position will hold the position from the list that are
// currently checked
String sql = "CREATE TABLE status (list_position INTEGER);";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Just for interface
}
}
}
After a quick test, the code works. It is just an example.
Related Topics
Android - Running a Method Periodically Using Postdelayed() Call
How to Select Multiple Images from Gallery in Android
How to Start an Activity from Within a Fragment
Kotlin Error:Could Not Find Org.Jetbrains.Kotlin:Kotlin-Stdlib-Jre7:1.0.7
Sync Scrolling of Multiple Recyclerviews
Firebase:Differencebetween Setpersistenceenabled and Keepsynced
Apache Http Connection with Android 6.0 (Marshmallow)
How to Import a Native Library (.So File) into Eclipse
Gridlayout and Row/Column Span Woe
Android Gridview Row Dividers/Separators
How to Run a Service Every Day at Noon, and on Every Boot
How to Reference an Asset in a Library Project
Gradle Sync Failed Could Not Find Constraint-Layout:1.0.0-Alpha2
Touch and Drag Image in Android
Place Imageview Over Button Android
Sqlite Exception No Such Column When Trying to Select
Why "This App Has Been Built with an Incorrect Configuration" Error Occured in Some Phones