2

I have made a listview with custom adapter. It has an Imageview, textview and a checkbox

---------------------------------------
 <ImageView --- textView --- checkbox >
---------------------------------------

I am using a SparseBooleanArray named "mCheckStates" to keep a track of the states of the checkboxes. Also I want to restrict users to check only two checkboxes at a time. for this I have used an int variable as a counter.

But when I scroll the listView onCheckChangedListener is being called and the count is reduced by one and sometimes by two, allowing user to check 3 or 4 checkboxes.

How can I stop this from happening? Please help me find a solution. Thanks.

Code

protected class MyCustomAdapter extends ArrayAdapter<String> implements
        CompoundButton.OnCheckedChangeListener {

    ArrayList<String> myList;
    int count = 0;
    ViewHolder holder = null;

    public MyCustomAdapter(Context context, int textViewResourceId,

    ArrayList<String> sList) {
        super(context, textViewResourceId, sList);
        mCheckStates = new SparseBooleanArray(sList.size());
        myList = sList;
    }

    private SparseBooleanArray mCheckStates;

    private class ViewHolder {
        TextView text;
        CheckBox chkbox;
        ImageView imageview;
    }

    @Override
    public int getCount() {
        return stg1.size();
    }

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

        if (convertView == null) {
            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.new_search_adptr, null);
            holder = new ViewHolder();
            holder.text = (TextView) convertView
                    .findViewById(R.id.adapterText1);
            holder.chkbox = (CheckBox) convertView
                    .findViewById(R.id.checkBox1);
            holder.imageview = (ImageView) convertView
                    .findViewById(R.id.imageView1);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.chkbox.setTag(position);
        holder.chkbox.setChecked(mCheckStates.get(position, false));
        holder.chkbox.setOnCheckedChangeListener(this);
        holder.text.setText(stg1.get(position).toString());
        holder.imageview.setImageBitmap(arr_img.get(position));
        return convertView;
    }

    public boolean isChecked(int position) {
        System.out.println("inside isChecked");
        return mCheckStates.get(position, false);
    }

    public void setChecked(int position, boolean isChecked) {
        System.out.println("inside setChecked");
        mCheckStates.put(position, isChecked);

    }

    public void toggle(int position) {
        System.out.println("inside toggle");
        setChecked(position, !isChecked(position));

    }

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

        System.out.println("\n inside onCheckedChanged: " + isChecked);

        if (isChecked) {
            System.out.println("inside isChecked true");
            System.out.println("count= " + count);

            if (count >= 2) {

                // count--;

                System.out.println("inside count>2: " + count);
                buttonView.setChecked(false);
                Toast.makeText(getApplicationContext(),
                        "Please select only two cars!", Toast.LENGTH_LONG)
                        .show();

            } else {

                count++;
                System.out.println("inside else: " + count);
                mCheckStates.put((Integer) buttonView.getTag(), isChecked);
            }

        } else {

            System.out.println("inside isChecked false" + count);
            mCheckStates.put((Integer) buttonView.getTag(), isChecked);
            count--;

        }

    }
}
lemons
  • 73
  • 8
  • Why don't you use diretly onClick() ? – An-droid Sep 23 '13 at 09:40
  • in onClick() also it might go in listener – lemons Sep 23 '13 at 09:42
  • In getview you use setchecked so it's normal that onCheckedChanged is called several times. On top of that GetView can be called more than necessary and you can't control that :/ Using OnClick() is more reliable i think – An-droid Sep 23 '13 at 09:44
  • okk so the listener should come inside getView function of outside separately? – lemons Sep 23 '13 at 09:48
  • @lemons although the link does not answer your question you can use it as a reference http://stackoverflow.com/questions/18162931/android-get-selected-item-using-checkbox-in-listview-when-i-click-a-button – Raghunandan Sep 23 '13 at 09:49

2 Answers2

0

I assume your CustomAdapter is for a ListView. So here is the thing, it is more confortable to check by clicking the cell.

So what you can do is setting a listener on your adater itself :

adapter .setOnItemClickListener();

Then in the activity/fragment you implement onItemClickListener

It will catch all the cell's click and provide you he position of the cell in the list.

If in your adapter you fill the cells with some Holder class and set it to the cell's tag you can get the holder in the onItemClick method :

FiltreCellHolder filtreCellHolder = null;                       

filtreCellHolder = (FiltreCellHolder) view.getTag();

Then according to you global check list you can test if this view is checked or not and since the user clicked it you check/unckeck it :

filtreCellHolder.cellCheck.setChecked(!filtreCellHolder.cellCheck.isChecked());
adapter.notifyDataSetChanged();
An-droid
  • 6,433
  • 9
  • 48
  • 93
0

I hope this will help you. Please change this code to your format

public class ImageAdapter extends BaseAdapter {
    private LayoutInflater mInflater;

    public ImageAdapter() {
        mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void initialize() {


        count = myList.size();
        thumbnailsselection = new boolean[count];
        notifyDataSetChanged();
    }

    public int getCount() {
        return arrPath.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.galleryitem, null);
            holder.imageview = (ImageView) convertView
                    .findViewById(R.id.thumbImage);
            holder.checkbox = (CheckBox) convertView
                    .findViewById(R.id.itemCheckBox);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.checkbox.setId(position);
        holder.imageview.setId(position);
        holder.imageview.setAdjustViewBounds(true);
        holder.checkbox.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                CheckBox cb = (CheckBox) v;
                int id = cb.getId();
                if (thumbnailsselection[id]) {
                    cb.setChecked(false);
                    thumbnailsselection[id] = false;
                } else {
                    cb.setChecked(true);
                    thumbnailsselection[id] = true;
                }
            }
        });


        holder.imageview.setImageBitmap(decodeFile(arrPath[position]));
        // holder.imageview.setScaleType(ScaleType.FIT_XY);
        // holder.imageview.setAdjustViewBounds(true);
        holder.checkbox.setChecked(thumbnailsselection[position]);
        holder.id = position;
        return convertView;
    }
}

Please check this condition in button click

final int len = thumbnailsselection.length;
            int cnt = 0;
            String selectImages = "";
            path = new ArrayList<String>();
            for (int i = 0; i < len; i++) {
                if (thumbnailsselection[i]) {
                    cnt++;
                    selectImages = arrPath[i];
                    path.add(selectImages);
                }
            }
            if (cnt == 0) {
                Toast.makeText(getApplicationContext(),
                        "Please select at least one image",
                        Toast.LENGTH_LONG).show();
            } else if (cnt > 5) {
                Toast.makeText(getApplicationContext(),
                        "Please select only 5 images", Toast.LENGTH_LONG)
                        .show();
            } else {}
Bebin T.N
  • 2,539
  • 1
  • 24
  • 28