【问题标题】:How to do put a CheckBox in a ListView?如何在 ListView 中放置 CheckBox?
【发布时间】:2014-01-13 16:44:37
【问题描述】:

我有一个带有自定义适配器的列表视图。在行的布局中,我有一个文本和一个复选框。 当我加载列表视图时,我从数据库中获取数据,它有一个列来确定该行是否被检查。当我加载列表时,它可以,必须保持选中的行,保持选中状态,其他行没有。问题是:当我取消选中一行并将列表向下和向上滚动时,当我返回开始时,我未选中的行再次返回选中,我该如何转售这个问题:

getView() 代码如下:

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;
}

【问题讨论】:

标签: android listview android-listview android-adapter android-checkbox


【解决方案1】:

我的猜测是,您可能没有选中 CheckBox,但您没有将其状态保存在任何地方,因此当该行通过滚动从屏幕上消失并且您再次向下滚动时,它会再次从数据库中加载数据并且已经签入。我不知道您如何处理您的 ArrayAdapter 扩展,但我建议将构造函数的 ArrayList 保存为类中的实例,在取消选中时更新其中的值,然后调用 notifyDataSetChanged()

---- 编辑----

要将ArrayList 存储在您的类中,您必须创建一个单独的类(包含您正在处理的两个字段),例如:

class MyRow {
  CheckBox cb;
  TextView tv;
}

因此,当您在 Activity 中声明自定义适配器时,您必须事先声明一个带有一些初始元素(甚至为空)的 ArrayList:

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

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

然后调用适配器类的构造函数,如下所示:

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

因此,当您将它传递给适配器类的构造函数时,您会在该类中保存它的副本:

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

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

所以现在,您更改的任何内容(例如选中/取消选中复选框)都必须将其状态保存在 myContent 数组中。您将在 getView() 方法中通过 getItem(position) 找到该项目并进行所需的更改。之后,您只需调用notifyDataSetChanged(); 方法,它就会自动显示您的ListView 中的更改。

【讨论】:

  • 你知道我该怎么做吗?
【解决方案2】:

几乎就像您的列表项在离开屏幕时被重新渲染或重新创建一样,现在最简单和明显的解决方案是在您的复选框被单击时触发一个事件,因此在您的适配器中创建一个 onclick 事件当复选框被选中或取消选中并更新数据源时触发。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    • 2014-11-29
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多