如何在Android中的ArrayAdapter中为复选框添加监听器,使用onCheckedChanged和OnCheckedChangeListener。

10

enter image description here

我有一个listView,通过ArrayAdapter填充小的xml子视图。每个小视图只有两个东西,一个复选框和其旁边的字符串标签。

我想设置一个onCheckedChanged监听器来捕获用户勾选或取消勾选复选框的事件。

例如,这里展示了一个监听器:

 listView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

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

 Toast.makeText(this, "box has been checked", Toast.LENGTH_SHORT).show();

 }

}

监听器代码应该放在你想要监听的事件发生的地方,并且需要设置它。以下是ArrayAdapter的代码:

  public class MobileArrayAdapter extends ArrayAdapter<CheckBoxInfo>{
    CheckBoxInfo[] objects;
    Context context;
    int textViewResourceId;

    public MobileArrayAdapter(Context context, int textViewResourceId,
        CheckBoxInfo[] objects) {
        super(context, textViewResourceId, objects);
        this.context = context;
        this.textViewResourceId = textViewResourceId;
        this.objects = objects;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row_layout_view = convertView;


            if ((row_layout_view == null)){


                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row_layout_view = inflater.inflate(R.layout.row_layout, null);
            }   

          //CheckBoxInfo item = objects.get(position);  // for arrayList
            CheckBoxInfo item = objects[position];

            if(item != null){

            TextView textView = (TextView) row_layout_view.findViewById(R.id.textView1);
            CheckBox checkBox = (CheckBox) row_layout_view.findViewById(R.id.checkBox1);

            if(item !=null){
            textView.setText(item.checkBoxName);
            checkBox.setChecked(item.checkBoxState);
               }
            }
            return row_layout_view;
    }


}
4个回答

37

不要使用示例 listView.setOnCheckedChangeListeneronCheckedChanged 代码。

首先,对于 CheckBox,应该使用 setOnClickListener() 而不是 setOnCheckedChangeListener()。你可以在 onClick() 函数中获取选中状态。

其次,将 setOnClickListener() 放置在列表适配器的 getView() 函数内部。

示例

checkBox.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View arg0) {
        final boolean isChecked = checkBox.isChecked();
        // Do something here.
    }
});

3
因为ListView回收视图,我认为这并不起作用。当您向下滚动并回收选定的convertView时,选中的行将变为未选中。你如何解决这个问题? - HukeLau_DABA
4
这是正确的行为。当一个 View 被重用时,它所有的子 View 都具有被回收的那个无意义 View 的特征。因此,每次在 getView() 中更新所有视图及其属性都是必要的,包括设置 CheckBox 值以及它的 OnClickListener。简而言之,在保留监听器的同时,添加 checkBox.setChecked() 来将其设置为期望值,以防回收(或新)视图具有不同的设置。 - David Manpearl

1

谢谢你,David!关于HukeLau_DABA的评论,我通过在OnClickListener()中更新带有CheckBox值的列表视图对象来解决了它。在我的情况下,我有一个地点列表,如下面的代码所示:

holder.placeCheckBox.setOnClickListener(new View.OnClickListener() {

       //please note that objPlace, position and holder must be declared 
       //as final inside the getView() function scope.   
          @Override
          public void onClick(View arg0) {
                final boolean isChecked = holder.placeCheckBox.isChecked();
                if (isChecked){
                   objPlace.setItemChecked("yes");
                }else{
                   objPlace.setItemChecked("no");
                }

                placesList.set(position,objPlace); //  updating the list with the updated object

            }
      });

1

在您的onClickListener中不要引用“holder.placeCheckBox”,而应该引用通过onClick传递的视图,并将其转换为CheckBox,因此代码应如下所示:

holder.placeCheckBox.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View arg0) {
            boolean isChecked = ((CheckBox)arg0).isChecked();
            if (isChecked){
               objPlace.setItemChecked("yes");
            }else{
               objPlace.setItemChecked("no");
            }

            placesList.set(position,objPlace); //  updating the list with the updated object

        }
  });

0
你可以尝试这个:
holder.placeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        Log.d(TAG, "onCheckedChanged: " + holder.placeCheckBox.getText() + " " + (b ? "selected":"deselected"));
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接