View in Android ListView without redrawing

I have an Android ListView that contains a single button that needs to be checked when clicked. The click event seems to work:

public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; LayoutInflater inflater = this._context.getLayoutInflater(); if (convertView == null) { convertView = inflater.inflate(R.layout.checkbox_cell, null); holder = new ViewHolder(); holder.checkbox = (CheckBox) convertView.findViewById(R.id.button); holder.textView = (TextView) convertView.findViewById(R.id.textView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } if(holder.checkbox.isChecked()) { convertView.setBackgroundColor(Color.RED); holder.textView.setBackgroundColor(Color.RED); convertView.invalidate(); } else { convertView.setBackgroundColor(Color.GREEN); } holder.checkbox.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Arrays.sort(_context.checkBoxIds); int index = Arrays.binarySearch(_context.checkBoxIds, position); if (((CheckBox) v).isChecked()) { holder.textView.setPaintFlags(holder.textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); } else { holder.textView.setPaintFlags(holder.textView.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG)); } holder.textView.setBackgroundColor(Color.RED); notifyDataSetChanged(); } }); return convertView; } 

As you can probably see that I am changing the background to green starting, when I click on the β€œcheckbox” the background should be red (this is just a test to see if the user interface is being updated). I tried updating the views in onClick , but this also does not work. After onClick I call notifyDataSetChanged() to see if the user interface changes during the upgrade. holder.checkbox.isChecked() seems to be true, but when I set the background to RED, the user interface will not be updated. Does anyone know what's wrong here? I don’t know at the moment.

+5
source share
6 answers

You must update the view based on the data view. However, you are updating the view based on the checkbox view state, which is never set before.

So, you must first update the check box based on the data part associated with the position, and after using further

+2
source

You can define the interface inside the adapter to listen to the flag and use setTag () on the flag and implement this interface on Fragment or Activity and define your definition inside the action or fragment.

+1
source

If you are debugging your code, I think if(holder.checkbox.isChecked()) { this line will always return false . This is due to the fact that you redefined the default CheckBox event, which should be switched to the verification status when you click on it, however after your redefinition you ignored it to switch the verification status, so the background cannot be changed to RED even after that how you released notifyDatasetChanged .

So try adding holder.checkbox.setChecked(!checkbox.isChecked()); on the first line of your OnClickListener to see if it helps.

+1
source

android: clickable = "true", please add this flag to this field in xml, then try with the code, when you ever perform some operation with the adapter, you need to update it.

+1
source

First of all, you need to remember which items in the list are marked and which are not. You can use a SparseBooleanArray .

Then in getView you need to set the view accordingly based on whether it has been marked or not.

Finally, you need to update the array whenever someone clicks on this checkbox.

 public class MyAdapter extends BaseAdapter { private SparseBooleanArray checkedItems = new SparseBooleanArray(); public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; LayoutInflater inflater = this._context.getLayoutInflater(); if (convertView == null) { // ... } else { // ... } holder.checkbox.setOnClickListener(null); // You may be reusing views, so avoid firing previous listener set holder.checkbox.setChecked(checkedItems.get(position, false)); // Set checked value for the checkbox based on your checked items array if(holder.checkbox.isChecked()) { // Do your stuff } else { // Do your stuff } holder.checkbox.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { checkedItems.put(position, ((CheckBox) v).isChecked()); // (!) // do stuff } }); return convertView; } } 

I put one line with (!) Because I never remember if the onClick event has an event on the checkbox old or new check state - you may need to add negation accordingly.

+1
source

Simple! .. You cannot find the same control after notifyDataSetChanged(); because this function updates the view with.

  public View getView(final int position, View convertView, ViewGroup parent) { return convertView; } 

so that you cannot set the flag to the same state, it updates all views.

you need to find the verification status as part of the data using any middleware class.

when you click, you make the data state.

  List<CheckState> checkState=new ArrayList<CheckState>();// as an instance holder.checkbox.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (((CheckBox) v).isChecked()) { checkState.add(new CheckState(true); } else{ checkState.add(position,false); } }); if(checkState.get(position).isChecked()) { convertView.setBackgroundColor(Color.RED); holder.textView.setBackgroundColor(Color.RED); convertView.invalidate(); } else { convertView.setBackgroundColor(Color.GREEN); } 

example: - create an inner class

  public class CheckState { boolean isChecked; public CheckState(boolean isChecked) { this.isChecked = isChecked; } public boolean isChecked() { return isChecked; } } 

I think this is good for you!

0
source

All Articles