35

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

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

假设我检查了某个复选框项目。然后我将它滚动到视野之外,然后再滚动回来。发生的事情是再次调用了侦听器。问题是我将复选框 ID 存储在此侦听器内的数组列表中,以便稍后在代码中使用它。结果是每次调用侦听器时都会向数组列表添加更多元素并扭曲数据。

有针对这个的解决方法吗?我应该怎么办?例如,我应该注销监听器吗?

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

8 回答 8

61

你用的是什么版本的安卓?

对于多个组件来说,这似乎是一个问题,尤其是对于 checkChange() 方法(CheckBox、RadioButton),我无法很好地解释为什么会发生这种情况。

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

无论如何,解决此问题的方法可能是添加一个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

      }
    });
于 2013-06-28T20:15:23.047 回答
20

OnCheckedChangeListener如果条件为我工作

if(buttonView.isShown())
{
    //ToDo code
}
于 2016-02-16T20:53:26.087 回答
11

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

android:saveEnabled="false"

这将确保 android 不会将检查状态存储到RestoreInstance,进而不会导致您经历的状态更改。

于 2015-10-16T16:44:19.907 回答
6

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

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

参考:在不触发 onCheckChanged 的​​情况下更改 Checkbox 值

于 2016-07-18T11:14:10.877 回答
4

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

@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
   if (buttonView.isShown()) { 
        if (buttonView.isChecked()) { 
             //Do something 
        } else { 
             //Do something 
        } 
    } 
}
于 2018-01-23T19:12:02.773 回答
1

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

于 2015-03-10T18:21:15.200 回答
1

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

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
}
        });
于 2017-02-15T08:21:04.167 回答
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();
                }
            });

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

于 2016-09-19T02:17:32.927 回答