What I have: a custom listview with Textviews and checkbox.
Problem: if I check the initial items that are shows on the screen and then I scroll the list, when I return to the top of the list (scroll up) their value is correctly saved. But if I scroll the list and for example I want to check the last tree checkboxs of my list then if I scroll up and down they become unchecked....WHY?**
I have seen various solution for the same problem in other forums and also here on stackoverflow, but the problem persists.
Below my getView function that I think is ok:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
viewHolder=new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.nameText.setTag(viewHolder.surnameText);
viewHolder.contactImage.setTag(data[position]);
viewHolder.checkBox.setChecked(data[position].isCheck());
viewHolder.checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
if(viewHolder.checkBox.isChecked()==true)
data[position].setCheck(true);
else
data[position].setCheck(false);
}
});
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.nameText.setText(data[position].getName());
viewHolder.surnameText.setText(data[position].getSurname());
viewHolder.contactImage.setImageResource(data[position].getPhotoRes());
viewHolder.contactImage.setScaleType(ScaleType.FIT_XY);
viewHolder.checkBox.setChecked(data[position].isCheck());
return convertView;
}
SOLVED: I solved my problem of getView whit this code:
public class NewQAAdapterSelectFriends extends BaseAdapter {
private LayoutInflater mInflater;
private Person[] data;
boolean[] checkBoxState;
ViewHolder viewHolder;
public NewQAAdapterSelectFriends(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setData(Person[] data) {
this.data = data;
checkBoxState=new boolean[data.length];
}
@Override
public int getCount() {
return data.length;
}
@Override
public Object getItem(int item) {
return data[item];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
viewHolder=new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.nameText.setText(data[position].getName());
viewHolder.surnameText.setText(data[position].getSurname());
viewHolder.contactImage.setImageResource(data[position].getPhotoRes());
viewHolder.contactImage.setScaleType(ScaleType.FIT_XY);
viewHolder.checkBox.setChecked(checkBoxState[position]);
viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(((CheckBox)v).isChecked()){
checkBoxState[position]=true;
data[position].setCheck(true);
}else{
checkBoxState[position]=false;
data[position].setCheck(false);
}
}
});
return convertView;
}
static class ViewHolder {
TextView nameText;
TextView surnameText;
ImageView contactImage;
CheckBox checkBox;
}
}
I have seen this tutorial to do my getView: http://androidcocktail.blogspot.it/2012/04/adding-checkboxes-to-custom-listview-in.html
When you use new
to create a class even in method, you have created a different scope for your variables. In other words:
// Creating a new scope here --> vvv
viewHolder.checkBox.setOnClickListener(new OnClickListener() {
// Any variables not visible to the entire class, won't work properly in here!
// (variables like: viewHolder, position, possibly data)
public void onClick(View arg0) {
if(viewHolder.checkBox.isChecked()==true)
data[position].setCheck(true);
else
data[position].setCheck(false);
}
}); // Exited "new class'" scope
position
is not the same position
that you think it is. Try saving the value of position
where you can reference it again:
viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
viewHolder.position = position;
convertView.setTag(viewHolder);
...
viewHolder.checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
data[viewHolder.position].setCheck(viewHolder.checkBox.isChecked());
}
});
Since you are dealing with a CheckBox though I would recommend using an OnCheckedChangeListener.
But you may not need to define any listeners for the ListView rows if you change the ChoiceMode:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With