0

hi I have checkboxes inside a listview I have eight choices, and I want the user to be able to check only four, then lock the checkboxes unless he unchecks one.

This my Main:

public class Ch2 extends Activity implements OnItemClickListener{
    ListView lv;
    ArrayAdapter<Model> adapter;
    List<Model> list = new ArrayList<Model>();
    int num;

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_ch2);

        lv = (ListView) findViewById(R.id.listView2);
        adapter = new cusCh2(this,getModel());
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
        TextView label = (TextView) v.getTag(R.id.label);
        final CheckBox checkbox = (CheckBox) v.getTag(R.id.check);
        checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
                if (isChecked){

                    Toast.makeText(getApplicationContext(),"hi",Toast.LENGTH_LONG);

                     // disable checkbox
                }
            }
        });
        Toast.makeText(v.getContext(), label.getText().toString()+" "+isCheckedOrNot(checkbox), Toast.LENGTH_LONG).show();

    }

    private String isCheckedOrNot(CheckBox checkbox) {
        if(checkbox.isChecked()) {
            num++;
            if (num == 4) {
                checkbox.setEnabled(false);

            }
            return "is checked";

        } else
            return "is not checked";
    }


    private List<Model> getModel() {
        list.add(new Model("a"));
        list.add(new Model("b"));
        list.add(new Model("c"));
        list.add(new Model("d"));
        list.add(new Model("e"));
        list.add(new Model("f"));
        list.add(new Model("m"));
        list.add(new Model("o"));
        return list;
    }

and this my ArrayAdapter

public class cusCh2  extends ArrayAdapter<Model> {

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


    public cusCh2(Activity context, List<Model> list) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
    }

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


    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {



    ViewHolder viewHolder = null;
    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        convertView = inflator.inflate(R.layout.row, null);
        viewHolder = new ViewHolder();
        viewHolder.text = (TextView) convertView.findViewById(R.id.label);
        viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.check);
        final ViewHolder finalViewHolder = viewHolder;
        final ViewHolder finalViewHolder1 = viewHolder;
        final ViewHolder finalViewHolder2 = viewHolder;
        viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.

            }
        });
        convertView.setTag(viewHolder);
        convertView.setTag(R.id.label, viewHolder.text);
        convertView.setTag(R.id.check, viewHolder.checkbox);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.checkbox.setTag(position); // This line is important.

    viewHolder.text.setText(list.get(position).getName());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());

    return convertView;
}
}

and this my model

public class Model {

    private String name;
    private boolean selected;

    public Model(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

of course I have row.xml file

as I say, I want to make my user able to check at most four boxes.

The solution I tried:

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
        list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
        if(!isChecked){
            num++;

            if(num>3){
               finalViewHolder.checkbox.setChecked(false);}
            if(!isChecked){
                num--;
                if(num<3){
                    finalViewHolder.checkbox.setChecked(true);}
            }


        }
    }
});

It's working as stop check, but when I scroll list, I lose what I already checked.

edit 2:

      viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

               int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
              list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.

               Toast toast=  Toast.makeText(getContext(), String.valueOf(getPosition), Toast.LENGTH_SHORT);

                if (isChecked) {
                    num++;
                    l.add(String.valueOf(getPosition));
                    if(l.size() > 3){    
                        finalViewHolder.checkbox.setChecked(false);
                    }         
                    toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 0);
                    toast.show();
                }

                    else if(!isChecked){
                    finalViewHolder.checkbox.setChecked(true);
                    }

            }

        });

also when i scroll i loss what i already checked

edit 2:

   viewHolder.checkbox.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                int getPosition = (Integer) v.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                list.get(getPosition).setSelected(finalViewHolder.checkbox.isChecked()); // Set the value of checkbox to maintain its state.
                Toast toast=  Toast.makeText(getContext(), String.valueOf(getPosition), Toast.LENGTH_SHORT);

                if (finalViewHolder.checkbox.isChecked()) {

                    l.add(String.valueOf(getPosition));
                    toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
                    toast.show();

                    if (l.size() > 4) {
                        finalViewHolder.checkbox.setChecked(false);
                    }


                    if (!finalViewHolder.checkbox.isChecked()) {
                        finalViewHolder.checkbox.setChecked(true);

                    }

                }
            }

        }
    );

I hope someone can help me, thanks.

chaos
  • 21
  • 5

3 Answers3

1

This is because when you scroll list setOnCheckedChangeListener will be called.evrytime when getView is called...instead of this use onClickListener on checkBox

   checkbox.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    if (checkbox.isChecked()) {

                    } else if (!checkbox.isChecked()) {

                        }
                    }

                }
            });
Meenal
  • 2,879
  • 5
  • 19
  • 43
  • well this make another problem after lock if try check then scroll then back the box will be checked automatic – chaos Jul 11 '15 at 14:20
  • cn u share ur code...u must be missing somethng..i think ur activity's oncreate is called again..if u lock or unlock – Meenal Jul 12 '15 at 12:38
  • i edit my question and add my code , work fine but one problem when lock and try to check one yes i cant but when scroll and back to one i tried it's checked automatic – chaos Jul 12 '15 at 14:05
0

You can use a list that store the checked items.You can put the checked item into list in OnCheckChangelistner/OnClicklistner.iF the user uncheck the item and it already in list than remove it from the list.And always check the size of list to count the items.You can choose the list type as you prefer like:- list or anything that stores the ids.

        holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // TODO Auto-generated method stub
               Log.e("checked : ", "Clicked on Checkbox: " +contactList.get(position).getName() +" is " + isChecked);




              ContactPhone cp = contactList.get(position);
              if(isChecked){
                  cp.setState(isChecked);
                  addToSelected(cp);

              }else{
                  cp.setState(isChecked);
                  removeSelected(cp);
              }

              if(selected_contats.size() > 4){

               }else{

                   }
               }

        }
    });

thats it...

SRB Bans
  • 3,096
  • 1
  • 10
  • 21
0

ok guys thx for your time i find my solution

the problem that even if u write checkbox.setChecked(false); the android still count as checked even if not with my Arraylist become increase what ever checked or not i stop this with make list remove last item when become setChecked(false); now it's work fine this solution code

     viewHolder.checkbox.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                int getPosition = (Integer) v.getTag();  

                if (finalViewHolder.checkbox.isChecked()) {

                    l.add(getItem(getPosition).getName());
                    Toast toast=  Toast.makeText(getContext(),String.valueOf(l.size()), Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
                    toast.show();

                    if (l.size() > 4) {
                        finalViewHolder.checkbox.setChecked(false);
                        l.remove(getItem(getPosition).getName());



                    }

                }
                   else if (!finalViewHolder.checkbox.isChecked()) {
                        l.remove(getItem(getPosition).getName());

                    }

                list.get(getPosition).setSelected(finalViewHolder.checkbox.isChecked());
            }

        }
    );
chaos
  • 21
  • 5