Question

I'm implementing a ListView with checkbox in witch cell. But the problem is when I check in one cell and roll down the list, it get confused and others cells get checked too. Do I havo to do something else in my getView method?

This is my CustonAdapter:

public class AcessoriosItemAdapter extends BaseAdapter {

ArrayList<AcessoriosItensLista> listAcessorios = new ArrayList<AcessoriosItensLista>();
Context context;    

public AcessoriosItemAdapter(Context context) {
    this.context = context;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return listAcessorios.size();
}

@Override
public Object getItem(int index) {
    // TODO Auto-generated method stub
    return listAcessorios.get(index);
}

@Override
public long getItemId(int index) {
    // TODO Auto-generated method stub
    return index;
}

@Override
public View getView(final int index, View view, ViewGroup parent) {

    if (view == null) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        view = inflater.inflate(R.layout.linha_acessorios, parent, false);             
    }       

    AcessoriosItensLista acessorios = (AcessoriosItensLista)getItem(index);

    ImageView imgAcessorio = (ImageView)view.findViewById(R.id.imgAcessorioLista);

    String nomeImagem = acessorios.getNomeImagens();
    int id = context.getResources().getIdentifier(nomeImagem, "drawable", context.getPackageName());
    imgAcessorio.setBackgroundResource(id); 

    TextView tvNome = (TextView) view.findViewById(R.id.tvNomeAcessoriosLinha);
    tvNome.setText(acessorios.getNomeAcessorio());      

    CheckBox cb = (CheckBox)view.findViewById(R.id.cbListaAcessorios);


    return view;
}   


public void addDadosAcessorios(String nomeAcessorio, String nomeImagens, boolean checked) {

    listAcessorios.add(new AcessoriosItensLista(nomeAcessorio, nomeImagens, checked));

}

}

Was it helpful?

Solution

The reason for this behaviour is because listview recycles the list item views. Since you do not reset the checked state in the getView() the state is maintained when you scroll and items gets recycled.

What is needed is a way to keep track of the state of each checkbox based on its position. So you could confidently tell: checkbox at position k is checked or not!

You need to keep track of the checkboxes which have been clicked so that when getView() is called, you can update the state of the checkbox.

1) Maintain a list of checkbox positions which are checked.

2) If checkbox is clicked and checked, add its position to the list. If it is clicked again (unchecked), remove it from the list.

3) Use this list and update the checked state of the checkbox in the getView()

Code:

public class AcessoriosItemAdapter extends BaseAdapter {

    ArrayList<AcessoriosItensLista> listAcessorios = new ArrayList<AcessoriosItensLista>(); 
    Context context;    

    // store a list of position where checbox is selected.
    ArrayList<Integer> checkedPositions = new ArrayList<Integer>();
    ...
    ...

    @Override
    public View getView(final int index, View view, ViewGroup parent) {

        if (view == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            view = inflater.inflate(R.layout.linha_acessorios, parent, false);             
        }       

        AcessoriosItensLista acessorios = (AcessoriosItensLista)getItem(index);

        ImageView imgAcessorio = (ImageView)view.findViewById(R.id.imgAcessorioLista);

        String nomeImagem = acessorios.getNomeImagens();
        int id = context.getResources().getIdentifier(nomeImagem, "drawable", context.getPackageName());
        imgAcessorio.setBackgroundResource(id); 

        TextView tvNome = (TextView) view.findViewById(R.id.tvNomeAcessoriosLinha);
        tvNome.setText(acessorios.getNomeAcessorio());      

        CheckBox cb = (CheckBox)view.findViewById(R.id.cbListaAcessorios);
        final Integer position = new Integer(index);

        // when checkbox is clicked, we add/remove its position to/from the list
        cb.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                if (((CheckBox) v).isChecked()) {
                    // if checked, we add it to the list
                    checkedPositions.add(position);
                }
                else if(checkedPositions.contains(position)) {
                    // else if remove it from the list (if it is present)
                    checkedPositions.remove(position);
                }

            }
        });
        // set the state of the checbox based on if it is checked or not.
        cb.setChecked(checkedPositions.contains(position));

        return view;
    }   

    ...
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top