问题
i have a trouble with listview. i added a checkbox into listview to choose items. my data is coming from sqlite so i use simple cursor adapter. length of my list is aproximatley 250 lines. i am clicking a check box.when i scroll down page (list), checkbox is clicked in every 10 lines.(for example in my screen show 10 lines data when i scroll 11th lines, this row's checkbox had clicked. how can i solve this problem.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/checkBox"
android:textStyle="bold"
android:text="TextView" />
<TextView
android:id="@+id/nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/nick"
android:layout_alignBottom="@+id/nick"
android:layout_alignParentRight="true"
android:text="TextView" />
<TextView
android:id="@+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/name"
android:layout_toRightOf="@+id/checkBox"
android:text="TextView" />
</RelativeLayout>
and this is source code package com.example.myprojects;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ListView;
public class send_message extends Activity {
private ListView list;
private EditText search;
SimpleCursorAdapter adapterx;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sendmessage);
list=(ListView)findViewById(R.id.list);
search=(EditText)findViewById(R.id.search);
loadfromdatabase();
}
private void loadfromdatabase() {
mydb info=new mydb(this);
info.open_read();
Cursor c = info.getAllData();
String[] columns = new String[] {mydb.KEY_NAME,mydb.KEY_PHONE, mydb.KEY_NICK};
int[] to = new int[] {R.id.name,R.id.phone, R.id.nick };
@SuppressWarnings("deprecation")
SimpleCursorAdapter adapter= new SimpleCursorAdapter(this, R.layout.activity_sendmesage_rows, c, columns, to,0);
list.setAdapter(adapter);
info.close();
}
}
回答1:
If you have CheckBox
es in ListView
you have problem, because ListView
reuses View
s that aren't already visible on screen. That's why when you scroll down, it loads (a few times) that one CheckBox
that was checked by you previously. So you can't rely on default CheckBox
's behaviour. What you need is:
Prevent user from checking
CheckBox
. You can do this by callingcb.setEnabled(false)
, wherecb
isCheckBox
which you are using.Create your own adapter class that will extend
SimpleCursorAdapter
. In this class you will storelist
of indexes of items that are checked.Override
getView()
method in your adapter class and there manually setCheckBox
to be checked if it's position is stored in checked items array.Create
OnClickListener
for yourListView
which will take care of adding/removing checked items' positions from adapter's internal array.
Edit:
This would be the code of your adapter:
public class MySimpleCursorAdapter extends SimpleCursorAdapter {
public ArrayList<Integer> mItemsChecked;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mItemsChecked = new ArrayList<Integer>();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
for(int i = 0; i < mItemsChecked.size(); i++) {
if(mItemsChecked.get(i) == position) {
CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkBox1); // Instead of checkBox1, write your name of CheckBox
cb.setChecked(true);
}
}
return super.getView(position, convertView, parent);
}
/* Just a handy method that will be responsible for adding/removing
items' positions from mItemsChecked list */
public void itemClicked(int position) {
for(int i = 0; i < mItemsChecked.size(); i++) {
if(mItemsChecked.get(i) == position) {
mItemsChecked.remove(i);
return;
}
}
mItemsChecked.add(position);
}
}
This is OnItemClickListener
for your ListView
:
final ListView lv = (ListView)findViewById(R.id.listView1); // Your ListView name
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
((MySimpleCursorAdapter)lv.getAdapter()).itemClicked(position);
lv.getAdapter().notifyDataSetChanged(); // Because we need to call getView() method for all visible items in ListView, so that they are updated
}
});
Just remember to disable your CheckBox
so that user can't click it.
Now you can see it as a little hack, because user doesn't click CheckBox
at all - application sees it as clicking in specific ListView
item, which in turn automatically checks appropriate CheckBox
for you.
回答2:
Here is simple example that will help you to implement that scenario
http://www.mysamplecode.com/2012/07/android-listview-checkbox-example.html
来源:https://stackoverflow.com/questions/17489119/listview-checkbox-trouble-in-android