自动调用 onCheckedChanged

我在回收视图中有一个开关,在从 DB 检索数据之后,数据显示在回收视图中。当回收视图打开时,我读数据库,如果数据库中的一个字段是“ Y”,我就启用交换机,否则我就禁用交换机。 现在的问题是,onCheckedChanged 侦听器也被调用,我希望只有当用户手动设置开关时才调用 onCheckedChanged。

在打开回收视图时,执行以下操作:

holder.enabledisable.setChecked(messengerRecord.get_is_valid().equalsIgnoreCase("Y"));

视图持有人类别:

public class viewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener{
public SwitchCompat enabledisable;
public viewHolder(View v) {
enabledisable = (SwitchCompat) v.findViewById(R.id.enabledisable);
enabledisable.setOnCheckedChangeListener(this);
...................................
...................................

OncheckedChanged 方法,在刚打开回收视图时调用该方法:

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.v("ranjith","called oncheckedchanged");
MessengerRecord rec;
rec = dbHelper.getRecord(descview.getText().toString());
switch (buttonView.getId()) {
case R.id.enabledisable:
if (isChecked) {
rec.set_is_valid("Y");
dbHelper.updateRecord(rec);
}
}

在布局文件中:

<android.support.v7.widget.SwitchCompat
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:id="@+id/enabledisable"
android:layout_alignRight="@+id/textview_to"
android:layout_alignEnd="@+id/textview_to"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
29882 次浏览

use a global boolean variable and when read a data from DB set it "true" and after check(if) in onCheckChange set it "false" again. in first of onCheckChange method check if this variable is false execute codes else return(default value of this variable must be false ) ;

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


Log.v("ranjith","called oncheckedchanged");
MessengerRecord rec;
rec = dbHelper.getRecord(descview.getText().toString());
switch (buttonView.getId()) {
case R.id.enabledisable:
if (isChecked) {
rec.set_is_valid("Y");
dbHelper.updateRecord(rec);


}
}//end if
isSourceDB = false; }// end oncheckedchange

It's weird all of us have this problem but not official Google answer to this simple problem.

The MOST simple it's to check:

buttonView.isPressed()

If true, means the user clicked the view.

No global variables are needed.

I faced the same problem inside ViewPager screen for fragments. When we switch between fragments, onCheckedChanged Listener is called again and again.

If anyone still looking for this problem, please try it.

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


if (buttonView.isInTouchMode()) {
... //Your code will come here.
}
}

I've ended up using this subclass of SwitchCompat to avoid this issue. This way I don't need boilerplate code where I'm using this class. Whenever you need to change the checked without firing the listener, use setCheckedSilent instead of setChecked:

import android.content.Context;
import android.os.Parcelable;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;


/**
* Created by emanuel on 30/5/16.
*/
public class Switch extends SwitchCompat {


private OnCheckedChangeListener listener;


public Switch(Context context, AttributeSet attrs) {
super(context, attrs);
}


@Override
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
this.listener = listener;
super.setOnCheckedChangeListener(listener);
}


@Override
public void onRestoreInstanceState(Parcelable state) {
super.setOnCheckedChangeListener(null);
super.onRestoreInstanceState(state);
super.setOnCheckedChangeListener(listener);
}


public void setCheckedSilent(boolean checked) {
super.setOnCheckedChangeListener(null);
super.setChecked(checked);
super.setOnCheckedChangeListener(listener);
}
}

onRestoreInstanceState was triggering the listening also, when set in the onViewCreated method and you are going back to a previous fragment. Hope it works for you!

This works for me:

 boolean selected = preferences.isChecked();
yourCheckBox.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (buttonView.isPressed()) {
preferences.setChecked(isChecked);
} else {
yourCheckBox.setChecked(selected);
}
}
});

Try this

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


if (buttonView.isPressed()) {
... //returns true, if user clicks the switch button
}}

Kotlin Developers:

    checkboxXYZ.setOnCheckedChangeListener { btnView, isChecked ->
if (btnView.isPressed) {


}
}

Since RecyclerView is recycling views, a previously attached OnCheckedChangeListener can be triggered when setting checked value for the Switch of the new item.

When binding new data to an item:

   switch.setOnCheckedChangeListener(null) // remove any existing listener from recycled view
switch.isChecked = [true/false] // will no longer trigger any callback to listener
switch.setOnCheckedChangeListener { btnView, isChecked ->
// do exiting stuff
}

If you are changing state in adapter then

   holder.rawManageDriverLayoutBinding.rawManageDriverSwitch.setOnCheckedChangeListener(null);

before setOnCheckedChangeListener.

Only solution is to use the method isPressed() in the listener