How to do put a CheckBox in a ListView?

断了今生、忘了曾经 提交于 2019-12-12 05:26:33

问题


I have a listview with a custon adapter. I the row's layout, I have a text and a checkbox. When I load the listview, I get the data from a database and it has one colunm that determine if the row is cheched or not. When I load the list, its ok, the rows that has to stay checked, stays checkd, and the others no. The problem is: when I unckheck a row ans roll the list down and up, when I return to the start, the row that I had unchecked, returns checked again, how can I resold this problem:

The getView() code below:

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

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

    final AcessoriosItensLista acessorios = (AcessoriosItensLista)getItem(index);

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

    final CheckBox cb = (CheckBox)view.findViewById(R.id.cbListaAcessorios);
    TextView tvNome = (TextView) view.findViewById(R.id.tvNomeAcessoriosLinha);
    tvNome.setText(acessorios.getNomeAcessorio());      

    final Integer iditem = Integer.valueOf(acessorios.getId());

    boolean ch = acessorios.isChecked();

    final Integer position = Integer.valueOf(index);

    if(ch){
        if(!checked.contains(iditem)){
            checkedPositions.add(position);
            checked.add(iditem);
        }
    }               

    cb.setOnClickListener(new OnClickListener() {           
        @Override
        public void onClick(View v) {
            if(checked.contains(iditem)){   
                checked.remove(iditem);
                checkedPositions.remove(position);
            }

            if (((CheckBox) v).isChecked()) {                  
                checkedPositions.add(position);       
                checked.add(iditem);
                int id = context.getResources().getIdentifier("acc_gold_"+acessorios.getId(), "drawable", context.getPackageName());
                imgAcessorio.setBackgroundResource(id);                      
            }
            else if(checkedPositions.contains(position)) {
                checkedPositions.remove(position);  
                checked.remove(iditem);
                int id = context.getResources().getIdentifier("acc_"+acessorios.getId(), "drawable", context.getPackageName());
                imgAcessorio.setBackgroundResource(id);                     
            }                   
        }
    }); 

    if(checkedPositions.contains(position)){
        cb.setChecked(true);    
        int id = context.getResources().getIdentifier("acc_gold_"+acessorios.getId(), "drawable", context.getPackageName());
        imgAcessorio.setBackgroundResource(id);                         
    } else {
        cb.setChecked(false);
        int id = context.getResources().getIdentifier("acc_"+acessorios.getId(), "drawable", context.getPackageName());
        imgAcessorio.setBackgroundResource(id);             
    }               

    return view;
}

回答1:


My guess is that probably you're unchecking that CheckBox but you're not saving its status anywhere, so when that row disappears from the screen by scrolling and you scroll down again, it loads the data again from the database and it's checked in it. I don't know how you're handling your ArrayAdapter extension, but I recommend saving the constructor's ArrayList as an instance inside the class, updating that value inside of it on uncheck, and call notifyDataSetChanged().

---- EDIT ----

To store the ArrayList inside your class, you'll have to create a separate class (with the two fields you're working on), for example:

class MyRow {
  CheckBox cb;
  TextView tv;
}

So when you declare your custom adapter in your Activity, you'll have to declare previously an ArrayList with some initial elements (or even empty):

ArrayList<MyRow> myList = new ArrayList<MyRow>();

MyRow row1 = new MyRow();
row1.cb.isChecked(...);
row1.tv.setText(...);
myList.add(row1);

Then you call the constructor of your adapter class, something like this:

MyArrayAdapter adapter = new MyArrayAdapter(context, R.layout.your_layout, myList);

So when you pass it to the constructor of your adapter class, you save a copy of it in that class:

public class MyArrayAdapter extends ArrayAdapter {
  final private ArrayList<MyRow> myContent;
  ...

  MyArrayAdapter(Context context, int my_layout, ArrayList<MyRow> myContent_) {
    ...
    myContent = myContent_
  }
}

So now, any content you change (like for example checking/unchecking a checkbox) you have to save its state in the myContent array. You would find that item by getItem(position) in your getView() method and make the changes you need. After it, you just have to call the notifyDataSetChanged(); method and it will automatically display the changes in your ListView.




回答2:


It's almost as it your list items are being re-redered or recreated when they go off screen, now the easiest and obvious solution here is to trigger an event when your checkbox is clicked so make an onclick event in your adapter that is triggered when the checkbox is checked or unchecked and updates the data source.



来源:https://stackoverflow.com/questions/21096674/how-to-do-put-a-checkbox-in-a-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!