当旧视图返回时,Android setOnCheckedChangeListener再次调用

时间:2013-06-28 20:01:28

标签: android checkbox android-listview listener expandablelistview

我无法解决getGroupView方法的问题。

问题是监听器setOnCheckedChangeListener被多次调用。

假设我检查某个复选框项。然后我将其滚出视图,然后向后滚动。发生的事情是再次调用侦听器。问题是我将checkbox-id存储在此侦听器内的arraylist中,以便稍后在代码中使用它。结果是每次调用侦听器时都会向arraylist添加更多元素并使数据失真。

有解决方案吗?我该怎么办?我应该取消注册听众吗?

@Override
 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
     View view = null;

     final int group_position = groupPosition;
     if (convertView == null) {
         LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         view = inflater.inflate(R.layout.activity_phrase, parent, false);
         final ViewHolder viewHolder = new ViewHolder();
         viewHolder.text = (TextView) view.findViewById(R.id.groupTitle);
         viewHolder.checkBox = (CheckBox) view.findViewById(R.id.check);
         viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub

                if (buttonView.isChecked()) {
                    checked.add((Integer) viewHolder.checkBox.getTag());
                }
                else {
                    checked.remove((Integer) viewHolder.checkBox.getTag());
                }

            }
        });

        view.setTag(viewHolder);
        viewHolder.checkBox.setTag(groupPosition);

     } else {
         view = convertView;
         ((ViewHolder)view.getTag()).checkBox.setTag(groupPosition);
     }

     ViewHolder holder = (ViewHolder) view.getTag();
     holder.text.setText(titles[groupPosition]);

     for (int i = 0; i < checked.size(); i++) {
         if (checked.get(i) == group_position) {
             holder.checkBox.setChecked(true);
         }
         else if (checked.get(i) != group_position) {
             holder.checkBox.setChecked(false);
         }
     }

     return view;
 }

8 个答案:

答案 0 :(得分:51)

您使用的是哪个版本的Android?

对于多个组件来说似乎是一个问题,特别是对于checkChange()方法(CheckBox,RadioButton),我无法提供一个很好的解释原因。

我会假设,因为它记录了位置状态的变化并抓住了其他属性的变化?解决了类似的问题here

在任何情况下,解决此问题的方法可能是添加OnClickListener()

CheckBox yourCheckBox = (CheckBox) findViewById (R.id.yourId);

yourCheckBox.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
                //is chkIos checked?
        if (((CheckBox) v).isChecked()) {
                         //Case 1
        }
        else 
          //case 2

      }
    });

答案 1 :(得分:14)

OnCheckedChangeListener只为一个条件

为我工作
if(buttonView.isShown())
{
    //ToDo code
}

答案 2 :(得分:6)

将以下内容添加到 ToggleButton 布局:

android:saveEnabled="false"

这样可以确保Android不会将检查状态存储到RestoreInstance,从而不会导致您遇到状态变化。

答案 3 :(得分:5)

在调用 setCheck()函数之前将侦听器设置为 null ,之后启用,如下所示:

checkBox.setOnCheckedChangeListener (null);
checkBox.setChecked(true);
checkBox.setOnCheckedChangeListener (this);

参考:Change Checkbox value without triggering onCheckChanged

答案 4 :(得分:2)

在OnCheckedChange方法中添加一个额外的if语句isShown(),它解决了多次调用OnCheckedChangeListener的问题。 无需更改为onClickListener:

@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
   if (buttonView.isShown()) { 
        if (buttonView.isChecked()) { 
             //Do something 
        } else { 
             //Do something 
        } 
    } 
}

答案 5 :(得分:1)

我遇到了同样的问题,并且花了几个小时看到所有与此相关的讨论。我试图通过保持来解决这个问题 viewHolder.checkBox.setTag(groupPosition);
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()这个监听器之前的这个陈述。代码完全符合预期。

答案 6 :(得分:0)

我遇到了同样的问题,并通过点击监听器

找到了解决方法

首先检查复选框是否分配了onclicklistener。如果不是这意味着适配器正在设置第一个的值。

if(!holder.checkbox.hasOnClickListeners())
        {
            holder.checkbox.setChecked(data.get( position ).getSelected());

        }

现在检查完

holder.checkbox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    data.get( position ).setSelected(holder.checkbox.isChecked());
                    holder.checkbox.setChecked(data.get( position ).getSelected());

                    Toast.makeText(getApplicationContext(),
                            data.get( position ).get_number()+" : "+position, Toast.LENGTH_LONG).show();
                }
            });

希望滚动问题消失。在这里工作正常。

答案 7 :(得分:0)

强文解决问题有很多方法

checkBoxSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
           // write here your code for example ...
              if(isChecked){
               // do somtheing when is checked
                   }else{
                       // do somthing when is removed the check**strong text**
                        }


        }
    });

**还有另一种方式**

    checkBoxSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(((CheckBox)v).isChecked()){
//do something
            }else{
//do something
}
        });