如何知道用户是否更改了切换按钮的状态?

20

我有十个切换按钮。当点击主页按钮时,我想保存其中五个按钮的状态。但只有在用户更改了任何一个按钮的状态时,我才想要保存它。有没有不使用setOnClickListener()就可以知道状态变化的方法?

8个回答

34

我已经做了以下的事情,它不是很好看,但它能起作用:

ttsButton = (ToggleButton) findViewById(R.id.solution_ttsbutton);
ttsButton.setOnCheckedChangeListener(toggleButtonChangeListener);
...
// gets called, if the button state changes
final CompoundButton.OnCheckedChangeListener toggleButtonChangeListener = new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // The user changed the button, do something
    }
};

如果我想在不执行更改监听器的情况下以编程方式更改按钮,则我会执行以下操作:

ttsButton.setOnCheckedChangeListener(null);
ttsButton.setChecked(false);
ttsButton.setOnCheckedChangeListener(toggleButtonChangeListener);

更清晰的示例和描述请参见:http://developer.android.com/guide/topics/ui/controls/togglebutton.html - ban-geoengineering

21

判断用户是否点击了CompoundButton(包括CheckBox, Switch, RadioButton, ToggleButton),有一种简单的方法,使用以下代码:

 new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
            if (compoundButton.isPressed()) {
                // do something related to user click/tap
            } else {
                // do something related to programmatically state changes (checked/unchecked)
            }
        }
    }

4
除非有人能证明.isPressed()不会在其他输入设备(如笔)上切换状态,否则这应该是被接受的答案(但我怀疑这种情况)。 - Daniel F
1
这个答案是正确的!我检查了几个测试用例,它都能正常工作! - MD. Shafiul Alam Biplob

15

使用 CompoundButton.OnCheckedChangeListener 类。

ToggleButton button = /* ... */;
button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // Save the state here
    }
});

编辑: 如果你想使用单个监听器:

CompoundButton.OnCheckedChangeListener listener =
        new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        String key = null;
        switch(buttonView.getId()) {
            case R.id.button1:
                key = "key1";
                break;
            case R.id.button2:
                key = "key2";
                break;
            default:
                return;
        }
        // Save the state here using key
    }
});

ToggleButton button1 = /* ... */;    
button1.setOnCheckedChangeListener(listener);

ToggleButton button2 = /* ... */;
button2.setOnCheckedChangeListener(listener);

但是有很多种方法来实现这个功能。因此,你可以想出另一种更适合你需要的方法,而不是使用这种方法。


我怎样可以为所有的切换按钮使用单一的监听器? - nila
11
我看到这段内容没有回答问题。更精确的表述应该是:如何区分button.setChecked(); 和用户点击?onCheckedChanged在两种情况下都会被调用。 - sydd
1
从问题中我可以看出,作者并不关心区分用户操作和方法调用,只是想知道按钮状态何时改变。 - Michael
我从选中的按钮得到了一个不同的id.getId()没有返回预期的id - Francisco Corrales Morales

3

Use a custom view

import android.content.Context;
import android.util.AttributeSet;
import android.widget.Switch;

public class CustomSwitch extends Switch {


    private OnCheckedChangeListener mListener;

    public CustomSwitch(Context context) {
        super(context);
    }

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

    public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        // Do not call supper method
        mListener = listener;
    }

    @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);

        if (mListener != null) {
            mListener.onCheckedChanged(this, checked);
        }
    }

    public void setCheckedProgrammatically(boolean checked) {
        // You can call super method, it doesn't have a listener... he he :)
        super.setChecked(checked);
    }

}

XML的示例用法

<com.your.package.CustomSwitch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

现在的想法是在代码中调用方法setCheckedProgrammatically。当用户更改复合按钮的状态时,Android会调用setChecked
请注意,我正在使用一个扩展了复合按钮的开关,您可以在任何其他类型的复选框等上基本上使用相同的代码。

2

对于Kotlin,请使用以下扩展:


fun CompoundButton.setOnUserCheckedChangeListener(callback: (isChecked: Boolean) -> Unit) {
    setOnCheckedChangeListener { buttonView, isChecked ->
        if (buttonView.isPressed) {
            callback.invoke(isChecked)
        }
    }
}

0

首先请检查此链接 http://developer.android.com/resources/tutorials/views/hello-formstuff.html#ToggleButton

一个简单的onChangeListener就可以了:

         public class TestProjectActivity extends Activity {

      ToggleButton one; 
     ToggleButton two;
    ToggleButton three;
     ToggleButton four;

    /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


one = (ToggleButton) findViewById(R.id.toggleButton1);
two = (ToggleButton) findViewById(R.id.toggleButton2);
three = (ToggleButton) findViewById(R.id.toggleButton3);
four = (ToggleButton) findViewById(R.id.toggleButton4);

one.setOnCheckedChangeListener(changeChecker);
two.setOnCheckedChangeListener(changeChecker);
three.setOnCheckedChangeListener(changeChecker);
four.setOnCheckedChangeListener(changeChecker);
      }

      OnCheckedChangeListener changeChecker = new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked){
        if (buttonView == one) {
            two.setChecked(false);
            three.setChecked(false);
            four.setChecked(false);
        }
        if (buttonView == two) {
            one.setChecked(false);
            three.setChecked(false);
            four.setChecked(false);
        }
        if (buttonView == three) {
            two.setChecked(false);
            one.setChecked(false);
            four.setChecked(false);
        }
        if (buttonView == four) {
            two.setChecked(false);
            three.setChecked(false);
            one.setChecked(false);
        }
    }
}
};

}

0
使用View.OnTouchListener监听用户交互事件。我在我的适配器类中实现了这个功能。
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder>
implements AccountUtils.OnAccountStateChange ,View.OnTouchListener{

// variable to store whether screen id pressed or not
public static boolean pressed=false;


//If User touches the screen 
//MotionEvent.ACTION_DOWN is triggred
//and when user lifts his hand (takes away from screen)
//MotionEvent.ACTION_UP is triggred
// Here you should the change the value of pressed accordingly
@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN:
        pressed = true;// Screen Touched
        break;
        case MotionEvent.ACTION_UP:
        pressed = false;// Screen 
        break;
    }
    return false;
}

static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    final SwitchCompat btnToggle;

    public ViewHolder(final View itemView) {
        super(itemView);

        btnToggle = (SwitchCompat) itemView.findViewById(R.id.btn_toggle);
        btnToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // IF the value in Var pressed is true 
                // only then trigger this event
                if (pressed) {

                    // YOUR METHOD GOES HERE
                    Toast.makeText(context, "Checked Changed",   Toast.LENGTH_SHORT).show();

                }
            }
        });

    }

}

}


0
我会推荐这个解决方案:https://dev59.com/UGox5IYBdhLWcg3wjE9i#9130007 简要来说,使用 "boolean CheckBox#isShown()" 来确定哪种情况,即使您在活动的 onStart() 或 onResume() 中修改了检查状态,它也会返回 false。(我还没有测试过片段场景。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接