Why my own ListAdapter does not work?

325 views Asked by At

the problem i have is when i click a chekbox and make the listview scroll-up the selected checkbox change or sometimes if a select the first checkbox so the last checkbox is selected too. I know my English is not good enough yet, sorry about it. Any help appreciated.

import java.util.ArrayList;
import java.util.Hashtable;


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;

public class MyListAdapter extends BaseAdapter{

     public static class ViewHolder {

         public CheckBox chkb = null;

    } 


    private LayoutInflater mInflater;

    private ArrayList<MyListAdapterItem> myListAdapterItems = null;

    private Hashtable<Object, Object> items = null;

    private boolean selectAll = false;

    private boolean readOnly = false;

    public MyListAdapter(Context context, ArrayList<MyListAdapterItem> myListAdapterItems, boolean selectAll, boolean readOnly) {

        mInflater = LayoutInflater.from(context);

        this.myListAdapterItems = myListAdapterItems;

        this.selectAll = selectAll;

        this.readOnly = readOnly;

        items = new Hashtable<Object, Object>();
    }

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

        ViewHolder viewHolder = null;

        if (convertView == null) {

            convertView = mInflater.inflate(R.layout.chkb_fila, null);

            viewHolder = new ViewHolder();

            viewHolder.chkb = (CheckBox) convertView.findViewById(R.id.chkbCultivo);

            convertView.setTag(viewHolder);

        }else {

            viewHolder = (ViewHolder) convertView.getTag();

        }

        items.put(myListAdapterItems.get(position), viewHolder.chkb);

        viewHolder.chkb.setText(myListAdapterItems.get(position).getDescription());

        if(selectAll){

            viewHolder.chkb.setChecked(true);
        }

        if(readOnly){

            viewHolder.chkb.setEnabled(false);

        }

        return convertView;

    }


    public int getCount() {

        return myListAdapterItems.size();

    }


    public Object getItem(int position) {

        return myListAdapterItems.get(position);

    }


    public long getItemId(int position) {

        return position;

    }

    /**
     * @return the myListItems
     */
    public ArrayList<MyListAdapterItem> getMySelectedListItems() {

        ArrayList<MyListAdapterItem> listSelectedItems = new ArrayList<MyListAdapterItem>();

        CheckBox tmpCheckBox = null;

        for(int i=0; i<items.size(); i++){

            tmpCheckBox = (CheckBox) items.get(myListAdapterItems.get(i));

            if(tmpCheckBox.isChecked()){

                listSelectedItems.add(myListAdapterItems.get(i));

            }

        }

        return listSelectedItems;

    }

}
3

There are 3 answers

1
Cristian On BEST ANSWER

Problem is that getView method reuses the views, thus you must make sure to update the checkboxs' states inside that method; that also implies that you must save that state somewhere.

0
Anthony Graglia On

Here are some links for you are looking for. Advanced but if you stick with it and dont give up on this, you will learn a ton!!! Take a look:

Android: ListView elements with multiple clickable buttons

Android custom list item with nested widgets

Rating bars and buttons on listItems

0
Kevin Galligan On

2 options.

1) Don't recycle your view. Always inflate a new one. That's "lazy", but if your app doesn't have too many entries, its less likely to introduce a bug.

2) Make sure you set everything on each view. You're reusing them, so if you've set something on one previously, it'll stay that way.

Change this:

if(selectAll){

        viewHolder.chkb.setChecked(true);
    }

    if(readOnly){

        viewHolder.chkb.setEnabled(false);

    }

to

        viewHolder.chkb.setChecked(selectAll);
        viewHolder.chkb.setEnabled(!readOnly);

With the if blocks, you're not setting the other side of the boolean value (you could also use else blocks, but that's more verbose).