11

multiple_checkboxes

In attached image, SelectAll checkbox is present with in an activity, and all checkboxes within adapter. If i checked SelectAll then all checkboxes are checked in adapter and if I unchecked then all are unchecked. Its happening nicely.

But I want if I checked SelectAll and after that if i uncheked one or more checkbox in tha adapter then the SelectAll checkbox should unchecked. and if without check to SelectAll If i manually check all the checkboxes in adapter then SelectAll checkbox should checked automatically.

How can I do that.

bellow is my code., http://pastebin.com/5pUJJC42

Jyosna
  • 4,436
  • 13
  • 60
  • 93
  • You should check the link below to solve ur problem.... here's the [link](http://stackoverflow.com/questions/7738527/getting-an-issue-while-checking-the-dynamically-generated-checkbox-through-list/7739006#7739006). – himanshu Nov 28 '11 at 07:15

7 Answers7

7

I did like below and I got my required output,

http://pastebin.com/PgNeDnXq

Jyosna
  • 4,436
  • 13
  • 60
  • 93
3

I tried it something like this,

Passed the checkAll checkbox to the Adapter class constructor and setting is Listener there itself so that we don't need to declare any flag public static from the Main Class.

Also I took couple of flags that maintain the state of the checkbox, that is I tried to maintain such that when the checkAll checkbox check is changed it does not effect the List Items checkbox and vice-versa for List Items checkbox check.

So, try this

public class myAdapter extends ArrayAdapter<Model> {

    private final List<Model> list;
    private final Activity context;
    private CheckBox checkAll;
    boolean checkAll_flag = false;
    boolean checkItem_flag = false;

    public myAdapter(Activity context, List<Model> list, CheckBox checkAll) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
        this.checkAll = checkAll;
        checkAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton checkbox, boolean arg1) {
                if(!checkItem_flag){
                    checkAll_flag = true;
                    notifyDataSetChanged(); 
                }
            }
        });
    }

    static class ViewHolder {
        protected TextView text;
        protected CheckBox checkbox;
    }

    private boolean areAllSelected() {

         boolean areAllSelected = false;

          for (int i = 0; i < list.size(); i++) {
              if(list.get(i).isSelected()){
                  areAllSelected = true;
              }
              else{
                  areAllSelected = false;
                  return areAllSelected;
              }
          }
          return areAllSelected;
        }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = null;
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            view = inflator.inflate(R.layout.row, null);
            final ViewHolder viewHolder = new ViewHolder();
            viewHolder.text = (TextView) view.findViewById(R.id.label);
            viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check);
            viewHolder.checkbox
                    .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            Model element = (Model) viewHolder.checkbox.getTag();
                            element.setSelected(buttonView.isChecked());

                            if(!checkAll_flag){
                                checkItem_flag = true;
                                if(buttonView.isChecked()){
                                    checkAll.setChecked(areAllSelected());
                                }
                                if(!buttonView.isChecked()){
                                    checkAll.setChecked(areAllSelected());                              
                                }
                                checkItem_flag = false;
                            }
                        }
                    });
            view.setTag(viewHolder);
            viewHolder.checkbox.setTag(list.get(position));
        } else {
            view = convertView;
            ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.text.setText(list.get(position).getName());
        holder.checkbox.setChecked(list.get(position).isSelected());    

        if(checkAll_flag){
            if(checkAll.isChecked()){
                holder.checkbox.setChecked(true);
            }
            else if(!checkAll.isChecked()){
                holder.checkbox.setChecked(false);
            }
            if(position == (list.size() -1)){
                checkAll_flag = false;
            }
        }
        return view;
    }
}
Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
3

I had a similar issue in the past. You need your row view to implement Checkable. Check this question.

Community
  • 1
  • 1
Macarse
  • 91,829
  • 44
  • 175
  • 230
2

You can make an array of booleans corresponding to list of items and in the adapter you should toggle the boolean values accordingly checked/unchecked, and in adapter on each and every check that is all elements of boolean array is true? then setchecked(true) the selectall_checkbox else keep it setchecked(unchecked).

mayank_droid
  • 1,015
  • 10
  • 19
  • Just check my code what I attached, I already did that using Model class where i took a boolean variable, and for each checked i am setting the values to that boolean. – Jyosna Nov 28 '11 at 07:18
  • Now another problem is if u click one checkbox within adapter its affecting to selectAll & all checkboxes in that adapter – Jyosna Nov 28 '11 at 10:23
  • No its not solving the problem. same problem still there – Jyosna Nov 28 '11 at 11:46
2

EDIT

Your adapter should look like this:

public class InteractiveArrayAdapter extends ArrayAdapter<Model> {
  private final List<Model> list;
  private final Activity context;
  private CheckBox selectAll;

  public InteractiveArrayAdapter( Activity context, List<Model> list, CheckBox selectAll ) {
    super( context, R.layout.list_items_attendance_payment, list );
    this.context = context;
    this.list = list;
    this.selectAll = selectAll;
  }

  static class ViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
  }

  @Override
  public View getView( final int position, View convertView, ViewGroup parent ) {
    View view = null;

    if( convertView == null ) {
      LayoutInflater inflator = context.getLayoutInflater();
      view = inflator.inflate( R.layout.list_items_attendance_payment, null );
      final ViewHolder viewHolder = new ViewHolder();
      viewHolder.text = (TextView) view.findViewById( R.id.name );
      viewHolder.checkbox = (CheckBox) view.findViewById( R.id.check );
      view.setTag( viewHolder );
    }
    else {
      view = convertView;
    }

    ViewHolder holder = (ViewHolder) view.getTag();
    holder.text.setText( list.get( position ).getName() );

    viewHolder.checkbox.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged( CompoundButton buttonView, boolean isChecked ) {
        AttendanceActivity.listMember.get( position ).setSelected( isChecked );
        list.get( position ).setSelected( buttonView.isChecked() );
        selectAll.setChecked( areAllSelected() ); // We just use the method as parameter as it returns a boolean.
      }
    } );

    if( selectAll.isChecked() )
      holder.checkbox.setChecked( true );
    else
      holder.checkbox.setChecked( list.get( position ).isSelected() );

    return view;
  }

  public void deselectAll() {
    for( Model element : list )
      element.setSelected( false );

    notifyDataSetChanged();
  }

  public void selectAll() {
    for( Model element : list )
      element.setSelected( true );

    notifyDataSetChanged();
  }

  private boolean areAllSelected() {
    for( Model element : list )
      if( !element.getSelected() )
        return false; // We conclude that not all are selected.

    return true; // All of the items were selected
  }
}

And the method in your Activity that set the OnCheckedChangedListener should be changed to this:

private void onClickSetAllAttendance() {
  selectAll.setOnClickListener( new OnClickListener() {
    @Override
    public void onClick( View v ) {
      CheckBox box = (CheckBox) v;
      box.toggle();

      if( box.isChecked() )
        listAdapter.selectAll();
      else
        listAdapter.deselectAll();
    }
  });
}
kaspermoerch
  • 16,127
  • 4
  • 44
  • 67
  • I tried with this code, but it still have some problem. If all are checked and if i ll uncheck one of them from adapter then selectAll checkbox should be uncheck but here all becoming unchecked. – Jyosna Dec 01 '11 at 09:47
  • Try chaning the `OnCheckedChangedListener` for `selectAll` to a `OnClickListener` as I have edited above. – kaspermoerch Dec 01 '11 at 10:02
2

Here is a simple solution for you.

@Override
public View getView(int position, View v, ViewGroup arg2) {
    final PillTime pillTime = arrPillTimes.get(position);
    if(v == null) {
        v = inflater.inflate(R.layout.select_time_row, null);
    }
    TextView tvTitle = (TextView)v.findViewById(R.id.tvTitle);
    TextView tvTime = (TextView)v.findViewById(R.id.tvTime);

    tvTime.setText(pillTime.getTime());

    final CheckBox cbtime = (CheckBox)v.findViewById(R.id.cbtime);
    cbtime.setChecked(false);
    for (PillTime pillTime2 : arrSelectedTimes) {
        if(pillTime2.getId().equals(pillTime.getId())) {
            cbtime.setChecked(true);
            break;
        }
    }
    tvTitle.setText(pillTime.getTitle());
    cbtime.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if(cbtime.isChecked()) {
                boolean contains = false;
                for (PillTime pillTime2 : arrSelectedTimes) {
                    if(pillTime2.getId().equals(pillTime.getId())) {
                        contains = true;
                        break;
                    }
                }
                if(!contains) {
                    arrSelectedTimes.add(pillTime);
                    if(arrPillTimes.size() == arrSelectedTimes.size()) {
                        cbSelectAll.setChecked(true);
                    }
                }
            }else {
                for (PillTime pillTime2 : arrSelectedTimes) {
                    if(pillTime2.getId().equals(pillTime.getId())) {
                        arrSelectedTimes.remove(pillTime2);
                        cbSelectAll.setChecked(false);
                        break;
                    }
                }
            }
        }
    });

    return v;
}

I have one main arrayList arrPillTimes which has all the data and I have second arrayList arrSelectedTimes which will keep the track of checked items.We will check if selected item is in arrSelectedTimes it means you have checked that item so you have to set checked property to true for that checkbox.

Dharmendra
  • 33,296
  • 22
  • 86
  • 129
1

try using CheckedTextView for this issue

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" android:background="#ffffff">

    <ListView
        android:id="@+id/listView"
        android:scrollbars="vertical" android:divider="#C0C0C0" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:cacheColorHint="#00000000" android:dividerHeight="1dip">
    </ListView>
    <LinearLayout android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:layout_width="match_parent">
        <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="All"></Button>
        <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="None"></Button>
        <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Done"></Button>
    </LinearLayout>

</LinearLayout>

listrow.xml

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/text"
   android:textAppearance="?android:attr/textAppearanceLarge"
   android:gravity="center_vertical"
   android:checkMark="?android:attr/listChoiceIndicatorMultiple"
   android:background="#ffffff" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textColor="#000000" android:padding="15dip"/>

CheckedTextVwActivity.java

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.Toast;

public class CheckedTextVwActivity extends Activity {
    /** Called when the activity is first created. */
    ListView listView;
    ListAdapter adapter;
    ArrayList<String> strings = new ArrayList<String>();
    Button button1,button2,button3;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listView = (ListView) findViewById(R.id.listView);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        strings.add(new String("B"));
        strings.add(new String("A"));
        TopicSelectionListAdapter topicSelectionListAdapter = new TopicSelectionListAdapter(
                CheckedTextVwActivity.this, R.layout.listrow, strings);
        listView.setAdapter(topicSelectionListAdapter);
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        for(int i=0;i<strings.size();i++){
            listView.setItemChecked(i, true);
        }

        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View view, int position,
                    long arg3) {
                CheckedTextView selectedItem = (CheckedTextView) view;
                boolean isChecked = selectedItem.isChecked();
                Log.e("TAG","item clicked position = " + position + " isChecked = " + isChecked);               
            }
        });

        button1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                for(int i=0;i<strings.size();i++){
                    listView.setItemChecked(i, true);
                }
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                for(int i=0;i<strings.size();i++){
                    listView.setItemChecked(i, false);
                }
            }
        });

        button3.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                int count = listView.getAdapter().getCount();
                String savedItems = null;
                for (int i = 0; i < count; i++) {

                    if (listView.isItemChecked(i)) {
                            savedItems = savedItems + listView.getItemAtPosition(i).toString() + ",";
                    }

                }
                Toast.makeText(CheckedTextVwActivity.this, ""+savedItems, Toast.LENGTH_LONG).show();
            }
        });


    }

    public class TopicSelectionListAdapter extends ArrayAdapter {
        @SuppressWarnings("unchecked")
        public TopicSelectionListAdapter(Context context,
                int textViewResourceId, List objects) {
            super(context, textViewResourceId, objects);
        }

        @Override
        public long getItemId(int currentPosition) {
            return super.getItemId(currentPosition);
        }

        @Override
        public View getView(int currentPosition, View convertView,
                ViewGroup parent) {
            View v = convertView;
            final LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listrow, null);
            final CheckedTextView textView = (CheckedTextView) v
            .findViewById(R.id.text);
            textView.setText(strings.get(currentPosition));
            return v;
        }
    }
}
ud_an
  • 4,939
  • 4
  • 27
  • 43