5

I have a Android ListView, which contains one button thats needs to be checked when clicked. The click event seems to be working:

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 probably can see i'm changing the background to green initial, when i click the "checkbox" the background needs to be red (this is just a test to see if the UI updates). I tried to update the views in the onClick, but thats not working either. After the onClick i call notifyDataSetChanged() to see if the UI changes when i refresh. The holder.checkbox.isChecked()seems to be true but when i set the background to RED the UI won't update. Does anyone know what goes wrong here? I'm clueless at the moment.

Leon Boon
  • 357
  • 3
  • 16
  • is there an @Override annotation inside Your code and You have just forget to post for Your onClickListener? – Opiatefuchs Sep 18 '15 at 09:44
  • Ah yes, forgot to post that. There is override :) – Leon Boon Sep 18 '15 at 09:48
  • @LeonBoon : [notifyDataSetChanged()](http://stackoverflow.com/a/12229903/1920735) will ask Listview to redraw the view, so when it redaw itself, it will refer to a fresh holder.checkbox.isChecked(), which will be false by default(guess),hence no red color background color appears. – avinash Sep 21 '15 at 10:40
  • Please try invalidate all the views that you want to change the backgrounds for . Eg, you are saying convertView.setBackgroundColor(Color.GREEN); but you are not invalidating it by saying convertView.invalidate(); – Simon Sep 21 '15 at 15:17
  • Is the checkbox getting toggled when you click on it? – Srujan Barai Sep 27 '15 at 05:17

6 Answers6

2

You should update the view based on your data representation. However you are updating view based on checkbox view state that is never set before.

So you should first update checkbox based on portion of data that related to the position and after use it further

Eugen Martynov
  • 19,888
  • 10
  • 61
  • 114
1

You can define interface inside adapter to listen checkbox click and use setTag() on Checkbox and implements that interface on Fragment or Activity and define your definition inside activity or fragment .

WinHtaikAung
  • 414
  • 2
  • 11
1

If you debug your code, I think if(holder.checkbox.isChecked()) { this line will always return false. That is because you have overriden the default on-click event of the CheckBox, which should be toggle the check status when clicking it, however after your overriden, you ignored to toggle the check status, that's why the background cannot be changed to RED even after you issued notifyDatasetChanged.

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

LiuWenbin_NO.
  • 1,216
  • 1
  • 16
  • 25
1

android:clickable="true" please add this tour check box in the xml then you try with your code , when ever you do some operation on adapter you need update with this .

impathuri
  • 574
  • 6
  • 21
1

First and foremost, you need to remember which items on the list are checked, and which are not. For this you can use a SparseBooleanArray.

Then in getView you need to set the view appropriately based on whether it's checked or not.

Finally you need to update the array whenever someone clicks on the 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 marked one line with (!) because I never remember whether onClick event on checkbox gives you old or new checked state - you may need to add negation appropriately.

wasyl
  • 3,421
  • 3
  • 27
  • 36
0

Its Simple!.. You don't find same control after notifyDataSetChanged(); because this function refresh view calling with.

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

so you can't get same state of check box it refresh all view.

you need to find check state as data part using any binder class.

when you click, you make a state of data.

    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 a inner class

    public class CheckState {

    boolean isChecked;

    public CheckState(boolean isChecked) {

        this.isChecked = isChecked;
    }

    public boolean isChecked() {
        return isChecked;
    }



}

I think it is helpful to you!

Neeraj Singh
  • 610
  • 9
  • 15