I am creating a list view with each row having custom layout. Each custom layout has a check-box. I have a check box, which on click has to click all the check boxes in the list view. I am able to click check boxes in visible rows but I am facing problem with non visible rows. I tried checking all in list adapter but its not working.
MainActivity.java
public class MainActivity extends Activity implements OnItemClickListener{
ListView listView;
ArrayAdapter<Model> adapter;
static List<Model> list = new ArrayList<Model>();
public static int count = 0;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.my_list);
adapter = new MyAdapter(this,getModel());
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
count = listView.getCount();
}
@Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
TextView label = (TextView) v.getTag(R.id.label);
CheckBox checkbox = (CheckBox) v.getTag(R.id.check);
Toast.makeText(v.getContext(), label.getText().toString()+" "+isCheckedOrNot(checkbox), Toast.LENGTH_LONG).show();
}
private String isCheckedOrNot(CheckBox checkbox) {
if(checkbox.isChecked())
return "is checked";
else
return "is not checked";
}
private List<Model> getModel() {
list.add(new Model("Linux"));
list.add(new Model("Windows7"));
list.add(new Model("Suse"));
list.add(new Model("Eclipse"));
list.add(new Model("Ubuntu"));
list.add(new Model("Solaris"));
list.add(new Model("Android"));
list.add(new Model("iPhone"));
list.add(new Model("Java"));
list.add(new Model(".Net"));
list.add(new Model("PHP"));
list.add(new Model("U1"));
list.add(new Model("S1"));
list.add(new Model("A1"));
list.add(new Model("i1"));
list.add(new Model("J1"));
list.add(new Model(".N1"));
list.add(new Model("PP1"));
return list;
}
}
MyAdapter .java
public class MyAdapter extends ArrayAdapter<Model> {
private final List<Model> list;
private final Activity context;
TextView text;
CheckBox checkbox;
boolean flag;
public MyAdapter(Activity context, List<Model> list) {
super(context, R.layout.row, list);
this.context = context;
this.list = list;
}
static class ViewHolder {
protected TextView text;
protected CheckBox checkbox;
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
final CheckBox c = (CheckBox) ((ViewGroup) parent.getParent()).getChildAt(0);
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
convertView = inflator.inflate(R.layout.row, null);
}
text = (TextView) convertView.findViewById(R.id.label);
checkbox = (CheckBox) convertView.findViewById(R.id.check);
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int getPosition = (Integer) buttonView.getTag();
list.get(getPosition).setSelected(buttonView.isChecked());
}
});
checkbox.setTag(position);
text.setText(list.get(position).getName());
c.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
for (int i = 0; i < parent.getChildCount(); i++) {
RelativeLayout r = (RelativeLayout) parent.getChildAt(i);
CheckBox check1 = (CheckBox) r.getChildAt(1);
if(check1 instanceof CheckBox){
check1.setChecked(true);
}
}
}
});
if(flag){
list.get(position).setSelected(flag);
}
checkbox.setChecked(list.get(position).isSelected());
return convertView;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="4dip"
android:layout_marginRight="10dip"
android:focusable="false"
android:focusableInTouchMode="false" >
</CheckBox>
<ListView
android:id="@+id/my_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
row.xml
<?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="wrap_content" >
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@+id/label"
android:textSize="30sp" >
</TextView>
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="4dip"
android:layout_marginRight="10dip"
android:focusable="false"
android:focusableInTouchMode="false" >
</CheckBox>
</RelativeLayout>
A list view only has as many children as you can see, therefore getChildCount()
will only return what is visible.
You will need to have a field in your Model
class that stores its checked
state. So in your adapter's getView
method you'll do something like
Model myModel = getItem(position);
checkBox.setChecked(myModel.isChecked());
Select all
should loop through the list and mark all Model
objects as checked and update the visible views in the list view. Next time you scroll the checkbox will read its checked state from the relevant model object, from inside getView()