What I have: a custom listview with Textviews and checkbox.
public class NewQAAdapterSelectFriends extends BaseAdapter { private LayoutInflater mInflater; private Person[] data; public NewQAAdapterSelectFriends(Context context) { mInflater = LayoutInflater.from(context); } public void setData(Person[] data) { this.data = data; } @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); final ViewHolder 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.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { Person element = (Person) viewHolder.checkBox.getTag(); if(isChecked){ element.setCheck(buttonView.isChecked()); //data[position].setCheck(true); //this is equivalent to previous line } else{ //to-do } } }); viewHolder.checkBox.setTag(data[position]); } else { } ViewHolder holder = (ViewHolder) convertView.getTag(); holder.nameText.setText(data[position].getName()); holder.surnameText.setText(data[position].getSurname()); holder.contactImage.setImageResource(data[position].getPhotoRes()); holder.contactImage.setScaleType(ScaleType.FIT_XY); holder.checkBox.setChecked(data[position].isCheck()); return convertView; } static class ViewHolder { TextView nameText; TextView surnameText; ImageView contactImage; CheckBox checkBox; } }
Thanks for the answers :)
EDIT: With the suggestion i changed my getView like below:
@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; }
SITUATION AFTER EDIT: Now, if i check the initial items that are shows on the screen and then I scrool the list, their value is correctly saved. But When I scroll the list and for example i want to check the last tree checkboxs of my list then after I scroll they become uncheked....BUT WHY??????
SOLVED: I solved my problem of getView with 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
I solved my problem just changing the "setOnCheckedChangeListener" to "setOnClickListener"
public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { CheckBox cbItemChecklist = new CheckBox(context); holder = new ViewHolder(); holder.cbItemChecklist = cbItemChecklist; convertView = cbItemChecklist; convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } final ItemChecklist itemChecklist = itensChecklist.get(position); holder.cbItemChecklist.setText(itemChecklist .getDescricaoItemChecklist()); holder.cbItemChecklist.setChecked(itemChecklist.isChecked()); holder.cbItemChecklist .setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(itemChecklist.isChecked()){ itemChecklist.setChecked(false); } else { itemChecklist.setChecked(true); } } }); return convertView; }
Check the code below -
public View getView(int position, View convertView, ViewGroup parent){ View view = convertView; ViewHolder holder = new ViewHolder(); if(view == null){ view = inflater.inflate(R.layout.list_callcycle_blue, null); holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container); holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc); holder.cb = (CheckBox) view.findViewById(R.id.cb_store); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } final Object data = getItem(position); holder.lblLabel.setText(data.getDescription()); holder.cb.setTag(position); holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { int position = (Integer) buttonView.getTag(); objects.get(position).setChecked(buttonView.isChecked()); } }); holder.cb.setChecked(isChecked(position)); return view; }
Always keep in mind, use change holder.cb.setOnCheckedChangeListener()
i.e. any listener before it's setting data, in our case it is holder.cb.setChecked()
Reason : When we scroll, listview will recycle the views, so if setchecked is used before listeners then it will pick values on the basis of old listener. And if we set it after listener, then it will take latest values
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