关于复选框:旧视图返回时,Android setOnCheckedChangeListener再次调用

Android setOnCheckedChangeListener calls again when old view comes back

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

问题在于侦听器setOnCheckedChangeListener被多次调用。

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

有解决方案吗?我应该怎么办?例如,我应该注销监听器吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@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;
 }

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

对于多个组件来说,这似乎是一个问题,尤其是对于一个checkedChange()方法(CheckBox,RadioButton)而言,我无法提供一个很好的解释原因。

我认为是因为它记录了位置状态的变化并获取了其他属性的变化?这里解决了类似的问题

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

      }
    });


如果条件

OnCheckedChangeListener为我工作了一个

1
2
3
4
if(buttonView.isShown())
{
    //ToDo code
}


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

1
android:saveEnabled="false"

这将确保android不会将检查状态存储到RestoreInstance,从而不会导致您遇到状态更改。


在调用setCheck()函数之前将侦听器设置为null,然后在其上启用该侦听器,例如:

1
2
3
checkBox.setOnCheckedChangeListener (null);
checkBox.setChecked(true);
checkBox.setOnCheckedChangeListener (this);

参考:在不触发onCheckChanged

的情况下更改复选框的值


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

1
2
3
4
5
6
7
8
9
@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   if (buttonView.isShown()) {
        if (buttonView.isChecked()) {
             //Do something
        } else {
             //Do something
        }
    }
}

我遇到了同样的问题,苦苦挣扎了几个小时,看到所有与此相关的讨论。我试图通过保持来解决这个问题
viewHolder.checkBox.setTag(groupPosition);
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()此侦听器之前的此语句。代码完全按预期工作。


强文本有很多方法可以解决此问题

1
2
3
4
5
6
7
8
9
10
11
12
13
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**
                        }


        }
    });

**还有另一种方式**

1
2
3
4
5
6
7
8
9
    checkBoxSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(((CheckBox)v).isChecked()){
//do something
            }else{
//do something
}
        });


我也遇到了同样的问题,并通过单击监听器找到了解决方法

首先检查该复选框是否分配了onclicklistener。如果不是,则表示适配器正在设置第一个的值。

1
2
3
4
5
if(!holder.checkbox.hasOnClickListeners())
        {
            holder.checkbox.setChecked(data.get( position ).getSelected());

        }

现在检查此

之后

1
2
3
4
5
6
7
8
9
10
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();
                }
            });

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