Reputation: 1244
Good day to all.
I have a list view with checkboxes near each textview. When I check one checkbox and scroll down, random other checkboxes also get checked. I've read this post and a couple others here and they all say that the state of each checkbox needs to be saved in a boolean list at getView()
. How would I go about doing that?
Thanks.
Edited for code:
This is the code of the adapter, containing also the getView()
method.
public class MyCustomAdapter extends BaseAdapter
{
public ArrayList<Error> list;
private Context mContext;
private LayoutInflater mInflator;
public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Error> list)
{
this.list = list;
this.mContext = context;
mInflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount()
{
return list.size();
}
@Override
public Error getItem(int position)
{
return list.get(position);
}
@Override
public long getItemId(int position)
{
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if(convertView == null)
{
holder = new ViewHolder();
convertView = mInflator.inflate(R.layout.listviewrow, null);
holder.text = (TextView)convertView.findViewById(R.id.text);
holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
final int pos = position;
holder.text.setText(list.get(position).getDescription());
holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
list.get(pos).setChecked(isChecked);
}
});
return convertView;
}
static class ViewHolder
{
TextView text;
CheckBox checkbox;
}
}
Upvotes: 2
Views: 25617
Reputation: 668
Below code working for me
My mainActivity
public class MainActivity extends Activity {
private ListView llChb;
private String[] data = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z" };
private ArrayList<String> arrData=null;
private ArrayList<InfoRowdata> infodata;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrData=new ArrayList<String>();
arrData.add("a");
arrData.add("b");
arrData.add("c");
arrData.add("d");
arrData.add("e");
arrData.add("f");
arrData.add("g");
arrData.add("h");
arrData.add("i");
arrData.add("j");
arrData.add("k");
arrData.add("l");
arrData.add("m");
arrData.add("n");
arrData.add("o");
arrData.add("p");
llChb = (ListView) findViewById(R.id.llChb);
infodata = new ArrayList<InfoRowdata>();
for (int i = 0; i < data.length; i++) {
infodata.add(new InfoRowdata(false, i));
// System.out.println(i);
//System.out.println("Data is == "+data[i]);
}
llChb.invalidate();
llChb.setAdapter(new MyAdapter());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row = null;
row = View.inflate(getApplicationContext(), R.layout.row, null);
TextView tvContent=(TextView) row.findViewById(R.id.tvContent);
//tvContent.setText(data[position]);
tvContent.setText(data[position]);
//System.out.println("The Text is here like.. == "+tvContent.getText().toString());
final CheckBox cb = (CheckBox) row
.findViewById(R.id.chbContent);
cb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (infodata.get(position).isclicked) {
infodata.get(position).isclicked = false;
} else {
infodata.get(position).isclicked = true;
}
for(int i=0;i<infodata.size();i++)
{
if (infodata.get(i).isclicked)
{
System.out.println("Selectes Are == "+ data[i]);
}
}
}
});
if (infodata.get(position).isclicked) {
cb.setChecked(true);
}
else {
cb.setChecked(false);
}
return row;
}
}
}
My InfoRowdata Model Class
public class InfoRowdata {
public boolean isclicked=false;
public int index;
/*public String fanId;
public String strAmount;*/
public InfoRowdata(boolean isclicked,int index/*,String fanId,String strAmount*/)
{
this.index=index;
this.isclicked=isclicked;
/*this.fanId=fanId;
this.strAmount=strAmount;*/
}
}
My MainXml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/llChb"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</RelativeLayout>
This is custom RowXml for ListView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rlMain"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="@+id/rlInner"
android:layout_width="fill_parent"
android:layout_height="50dp" >
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:text="Medium Text"
android:textColor="#000000" />
<CheckBox
android:id="@+id/chbContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp" />
</RelativeLayout>
</RelativeLayout>
Upvotes: 10
Reputation: 1
If still your looking for answer here it goes. Some are commented in stackoverflow that , if we are using Custom Adapter or Custom ListView then we have to remember checkbox status. But no need to remember. ListView will remember it. So before implementation please understand the below items.
Once you learn above mentioned points then answer is very simple. ListView will remember all the status and can be extracted using isItemChecked by passing position as parameter.
Upvotes: -1
Reputation: 4217
Use this
ViewHolder holder;
holder = new ViewHolder();
convertView = mInflator.inflate(R.layout.listviewrow, null);
holder.text = (TextView)convertView.findViewById(R.id.text);
holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
Instead of
ViewHolder holder;
if(convertView == null)
{
holder = new ViewHolder();
convertView = mInflator.inflate(R.layout.listviewrow, null);
holder.text = (TextView)convertView.findViewById(R.id.text);
holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
I faced same problem. May be you will get answer !
Upvotes: 0
Reputation: 1165
View in listView are recycled, it means that when a view is going out of the screen, it is reused for the next view to appear. That's mean also, that if you don't set the checkbox to any state you want, it will keep the state from the recycled view.
What kind of adapter do you use ?
Upvotes: 3