web-dev-qa-db-ja.com

Android setOnCheckedChangeListenerは、古いビューが戻ったときに再度呼び出します

GetGroupView-methodの問題を解決できません。

問題は、リスナーsetOnCheckedChangeListenerが何度も呼び出されることです。

特定のチェックボックス項目をチェックするとします。それから私はそれをビューの外にスクロールし、次にスクロールバックします。何が起こるかというと、リスナーがもう一度呼び出されます。そして問題は、このリスナー内のarraylistにcheckbox-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;
 }
28

Android=のどのバージョンを使用していますか?

特にcheckedChange()メソッド(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

      }
    });
53
Alexey

OnCheckedChangeListenerはif条件を1つ使用して働いた

if(buttonView.isShown())
{
    //ToDo code
}
16
Sonal Bausakar

以下をToggleButtonレイアウトに追加します。

Android:saveEnabled="false"

これにより、Androidがチェック状態をRestoreInstanceに保存せず、順番に状態が変化することはありません。

6

nullにリスナーを設定してから、setCheck()関数を呼び出し、enableその後、次のように:

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

参照: onCheckChangedをトリガーせずにチェックボックスの値を変更する

5
Mahmoud Ibrahim

OnCheckedChangeメソッドにifステートメントisShown()を追加すると、OnCheckedChangeListenerが複数回呼び出されるという問題が解決します。 onClickListenerに変更する必要はありません。

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

私は同じ問題に直面し、これに関連するすべての議論を見ながら数時間苦労しました。 viewHolder.checkBox.setTag(groupPosition);を維持することでこれを修正しようとしました
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()このリスナーの前のこのステートメント。また、コードは期待どおりに機能します。

1
anoop

strong text問題を解決する方法はたくさんあります

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
}
        });
0
Ahmad Saleh

私は同じ問題に悩まされていて、on click listenerを使用して回避策を見つけました

最初に、チェックボックスに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();
                }
            });

スクロールの問題が解決することを願っています。ここで正常に動作します。

0
farhan678