ListView Viewholder Flag State

I have some problems with my ListView adapter (and its recently implemented viewHolder). I have a ListView with a checkbox for each item (nothing new here). The problem is that if there are more than 9 elements in my list, when I check the first checkbox, the tenth will be automatically checked (the same for the second and eleventh), as if there was one listener for both elements (and I believe in this matter in some way).

I read the position question with listView, view the utility and ViewHolder method for solving it here: How can I make my ArrayAdapter next to the ViewHolder template?

But I probably did something wrong, because it does not work ...

public class PresenceListAdapter extends SimpleAdapter { private LayoutInflater inflater; private List<Integer> ids; private List<String> statuts; public PresenceListAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to, List<Integer> ids, List<String> statuts) { super (context, data, resource, from, to); inflater = LayoutInflater.from (context); this.ids = ids; this.statuts= statuts; } @Override public Object getItem (int position) { return super.getItem (position); } @Override public View getView (int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate (R.layout.list_text_checkbox, null); holder = new ViewHolder(); holder.btn = (Button) convertView.findViewById(R.id.btnRetard); holder.check = (CheckBox) convertView.findViewById(R.id.checkPresent); if (statuts.get(position).equals("P")) { Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_online); holder.btn.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null ); holder.btn.setEnabled(true); holder.check.setChecked(true); } else if(statuts.get(position).equals("R")) { Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_away); holder.btn.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null ); holder.btn.setEnabled(true); holder.check.setChecked(true); } else { Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_invisible); holder.btn.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null ); holder.check.setChecked(false); } convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } int id = ids.get(position); if(id != 0) { holder.check.setTag(id); holder.btn.setTag(id); } return super.getView (position, convertView, parent); } static class ViewHolder { Button btn; CheckBox check; } 

And my listener: public void changerPresent (View v) {

  CheckBox checkPresent = (CheckBox) v; int idPersonne = (Integer) checkPresent.getTag(); View parent = (View)v.getParent(); Button btn = (Button) parent.findViewById(R.id.btnRetard); if(checkPresent.isChecked()) { gestion.updatePresence(idPersonne, idSeance, "P"); btn.setEnabled(true); setBtnRetardPresent(btn); } else { gestion.updatePresence(idPersonne, idSeance, "A"); btn.setEnabled(false); setBtnRetardAbsent(btn); } } 

I would be grateful for any help at this stage, I am working on this watch.

Thank you very much.

+6
source share
3 answers

Here is how I did it:

First you need a separate array for your checked state. It should be the same size as your getCount() adapter.

Then on your getView your checkbox setOnCheckedChangedListener MUST STOP your checkbox.set Validated statements.

Example:

 holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { isChecked[position] = isChecked; } }); holder.checkBox.setChecked(isChecked[position]); 
+13
source

The problem is that listview is processing it as views

therefore in getView( ) method

  if (convertView == null) { ........ } else { holder = (ViewHolder) convertView.getTag(); } // Uncheck needed boxes here... You need to implement your logic if( 'position' is checked earlier) holder.check.setChecked(true); else holder.check.setChecked(false); 

You need to write code to control the state of the view if the transformation is not null, because it is an already used view that can be checked.

0
source

You must set the state of the CheckedBox outside of the ViewHolder initialization, for example, the following code:

 if (convertView == null) { viewHolder = new ViewHolder(); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.checkedBox.setChecked(); 

BTW: use a SparseBooleanArray instead of two lists to store the state of the CheckedBox.

0
source

Source: https://habr.com/ru/post/944169/


All Articles