android.widget.Switch - 开/关事件监听器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11278507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android.widget.Switch - on/off event listener?
提问by Johan
I would like to implement a switch button, android.widget.Switch (available from API v.14).
我想实现一个开关按钮 android.widget.Switch(可从 API v.14 获得)。
<Switch
android:id="@+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Switch" />
But I'm not sure how to add an event listener for the button. Should it be an "onClick" listener? And how would I know if it is toggled "on" or not?
但我不确定如何为按钮添加事件侦听器。它应该是一个“onClick”监听器吗?我怎么知道它是否“打开”?
回答by Sam
Switch inherits CompoundButton
's attributes, so I would recommend the OnCheckedChangeListener
开关继承CompoundButton
的属性,所以我会推荐OnCheckedChangeListener
mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// do something, the isChecked will be
// true if the switch is in the On position
}
});
回答by shridutt kothari
Use the following snippet to add a Switch to your layout via XML:
使用以下代码段通过 XML 将 Switch 添加到您的布局:
<Switch
android:id="@+id/on_off_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="OFF"
android:textOn="ON"/>
Then in your Activity's onCreate method, get a reference to your Switch and set its OnCheckedChangeListener:
然后在您的 Activity 的 onCreate 方法中,获取对您的 Switch 的引用并设置其 OnCheckedChangeListener:
Switch onOffSwitch = (Switch) findViewById(R.id.on_off_switch);
onOffSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.v("Switch State=", ""+isChecked);
}
});
回答by Faheel
For those using Kotlin, you can set a listener for a switch (in this case having the ID mySwitch
) as follows:
对于使用 Kotlin 的用户,您可以为开关设置监听器(在本例中为 ID mySwitch
),如下所示:
mySwitch.setOnCheckedChangeListener { _, isChecked ->
// do whatever you need to do when the switch is toggled here
}
isChecked
is true if the switch is currently checked (ON), and false otherwise.
isChecked
如果开关当前处于选中状态 (ON),则为 true,否则为 false。
回答by neferpitou
Define your XML layout:
定义您的 XML 布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.neoecosystem.samplex.SwitchActivity">
<Switch
android:id="@+id/myswitch"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</RelativeLayout>
Then create an Activity
然后创建一个Activity
public class SwitchActivity extends ActionBarActivity implements CompoundButton.OnCheckedChangeListener {
Switch mySwitch = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_switch);
mySwitch = (Switch) findViewById(R.id.myswitch);
mySwitch.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// do something when check is selected
} else {
//do something when unchecked
}
}
****
}
======== For below API 14use SwitchCompat =========
======== 对于低于 API 14使用 SwitchCompat ==========
XML
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.neoecosystem.samplex.SwitchActivity">
<android.support.v7.widget.SwitchCompat
android:id="@+id/myswitch"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</RelativeLayout>
Activity
活动
public class SwitchActivity extends ActionBarActivity implements CompoundButton.OnCheckedChangeListener {
SwitchCompat mySwitch = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_switch);
mySwitch = (SwitchCompat) findViewById(R.id.myswitch);
mySwitch.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// do something when checked is selected
} else {
//do something when unchecked
}
}
*****
}
回答by Abish R
The layout for Switch widget is something like this.
Switch 小部件的布局是这样的。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:gravity="right"
android:text="All"
android:textStyle="bold"
android:textColor="@color/black"
android:textSize="20dp"
android:id="@+id/list_toggle" />
</LinearLayout>
In the Activity class, you can code by two ways. Depends on the use you can code.
在 Activity 类中,您可以通过两种方式进行编码。取决于您可以编码的用途。
First Way
第一种方式
public class ActivityClass extends Activity implements CompoundButton.OnCheckedChangeListener {
Switch list_toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.return_vehicle);
list_toggle=(Switch)findViewById(R.id.list_toggle);
list_toggle.setOnCheckedChangeListener(this);
}
}
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
if(isChecked) {
list_toggle.setText("Only Today's"); //To change the text near to switch
Log.d("You are :", "Checked");
}
else {
list_toggle.setText("All List"); //To change the text near to switch
Log.d("You are :", " Not Checked");
}
}
Second way
第二种方式
public class ActivityClass extends Activity {
Switch list_toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.return_vehicle);
list_toggle=(Switch)findViewById(R.id.list_toggle);
list_toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
list_toggle.setText("Only Today's"); //To change the text near to switch
Log.d("You are :", "Checked");
}
else {
list_toggle.setText("All List"); //To change the text near to switch
Log.d("You are :", " Not Checked");
}
}
});
}
}
回答by Ali hasan
You can use DataBinding and ViewModel for Switch Checked Change event
您可以将 DataBinding 和 ViewModel 用于 Switch Checked Change 事件
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.example.ui.ViewModel" />
</data>
<Switch
android:id="@+id/on_off_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onCheckedChanged="@{(button, on) -> viewModel.onCheckedChange(on)}"
/>
回答by AndrewBloom
My solution, using a SwitchCompat
and Kotlin. In my situation, i needed to react to a change only if the user triggered it through the UI. In fact, my switch reacts to a LiveData
, and this made both setOnClickListener
and setOnCheckedChangeListener
unusable. setOnClickListener
in fact reacts correctly to user interaction, but it's not triggered if the user drags the thumb across the switch. setOnCheckedChangeListener
on the other end is triggered also if the switch is toggled programmatically (for example by an observer). Now in my case the switch was present on two fragments, and so onRestoreInstanceState would trigger in some cases the switch with an old value overwriting the correct value.
我的解决方案,使用 aSwitchCompat
和 Kotlin。在我的情况下,只有当用户通过 UI 触发更改时,我才需要对更改做出反应。事实上,我的开关做出反应到LiveData
,这使双方setOnClickListener
和setOnCheckedChangeListener
无法使用。setOnClickListener
实际上对用户交互做出正确反应,但如果用户将拇指拖过开关,则不会触发。setOnCheckedChangeListener
如果以编程方式切换开关(例如由观察者),则另一端也会触发。现在,在我的情况下,开关存在于两个片段上,因此 onRestoreInstanceState 在某些情况下会触发开关,旧值覆盖正确值。
So, i looked at the code of SwitchCompat, and was able to mimic it's behaviour successfully in distinguishing click and drag and used that to build a custom touchlistener that works as it should. Here we go:
所以,我查看了 SwitchCompat 的代码,并且能够成功地模仿它在区分点击和拖动方面的行为,并使用它来构建一个可以正常工作的自定义触摸侦听器。开始了:
/**
* This function calls the lambda function passed with the right value of isChecked
* when the switch is tapped with single click isChecked is relative to the current position so we pass !isChecked
* when the switch is dragged instead, the position of the thumb centre where the user leaves the
* thumb is compared to the middle of the switch, and we assume that left means false, right means true
* (there is no rtl or vertical switch management)
* The behaviour is extrapolated from the SwitchCompat source code
*/
class SwitchCompatTouchListener(private val v: SwitchCompat, private val lambda: (Boolean)->Unit) : View.OnTouchListener {
companion object {
private const val TOUCH_MODE_IDLE = 0
private const val TOUCH_MODE_DOWN = 1
private const val TOUCH_MODE_DRAGGING = 2
}
private val vc = ViewConfiguration.get(v.context)
private val mScaledTouchSlop = vc.scaledTouchSlop
private var mTouchMode = 0
private var mTouchX = 0f
private var mTouchY = 0f
/**
* @return true if (x, y) is within the target area of the switch thumb
* x,y and rect are in view coordinates, 0,0 is top left of the view
*/
private fun hitThumb(x: Float, y: Float): Boolean {
val rect = v.thumbDrawable.bounds
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
}
override fun onTouch(view: View, event: MotionEvent): Boolean {
if (view == v) {
when (MotionEventCompat.getActionMasked(event)) {
MotionEvent.ACTION_DOWN -> {
val x = event.x
val y = event.y
if (v.isEnabled && hitThumb(x, y)) {
mTouchMode = TOUCH_MODE_DOWN;
mTouchX = x;
mTouchY = y;
}
}
MotionEvent.ACTION_MOVE -> {
val x = event.x
val y = event.y
if (mTouchMode == TOUCH_MODE_DOWN &&
(abs(x - mTouchX) > mScaledTouchSlop || abs(y - mTouchY) > mScaledTouchSlop)
)
mTouchMode = TOUCH_MODE_DRAGGING;
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_CANCEL -> {
if (mTouchMode == TOUCH_MODE_DRAGGING) {
val r = v.thumbDrawable.bounds
if (r.left + r.right < v.width) lambda(false)
else lambda(true)
} else lambda(!v.isChecked)
mTouchMode = TOUCH_MODE_IDLE;
}
}
}
return v.onTouchEvent(event)
}
}
How to use it:
如何使用它:
the actual touch listener that accepts a lambda with the code to execute:
实际的触摸侦听器,它接受带有要执行的代码的 lambda:
myswitch.setOnTouchListener(
SwitchCompatTouchListener(myswitch) {
// here goes all the code for your callback, in my case
// i called a service which, when successful, in turn would
// update my liveData
viewModel.sendCommandToMyService(it)
}
)
For the sake of completeness, this is how the observer for the state switchstate
(if you have it) looked like:
为了完整起见,这就是状态的观察者switchstate
(如果有的话)的样子:
switchstate.observe(this, Observer {
myswitch.isChecked = it
})
回答by Mrudul Addipalli
there are two ways,
有两种方式,
using xml onclick view Add Switch in XML as below:
<Switch android:id="@+id/switch1" android:onClick="toggle"/>
使用 xml onclick 视图在 XML 中添加开关,如下所示:
<Switch android:id="@+id/switch1" android:onClick="toggle"/>
In YourActivity Class (For E.g MainActivity.java)
在 YourActivity 类中(例如 MainActivity.java)
Switch toggle; //outside oncreate
toggle =(Switch) findViewById(R.id.switch1); // inside oncreate
public void toggle(View view) //outside oncreate
{
if( toggle.isChecked() ){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
start.setBackgroundColor(getColor(R.color.gold));
stop.setBackgroundColor(getColor(R.color.white));
}
}
else
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
stop.setBackgroundColor(getColor(R.color.gold));
start.setBackgroundColor(getColor(R.color.white));
}
}
}
- using on click listener
- 使用点击监听器
Add Switch in XML as below:
在 XML 中添加 Switch 如下:
In YourActivity Class (For E.g MainActivity.java)
在 YourActivity 类中(例如 MainActivity.java)
Switch toggle; // outside oncreate
toggle =(Switch) findViewById(R.id.switch1); // inside oncreate
toggle.setOnClickListener(new View.OnClickListener() { // inside oncreate
@Override
public void onClick(View view) {
if( toggle.isChecked() ){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
start.setBackgroundColor(getColor(R.color.gold));
}
}
else
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
stop.setBackgroundColor(getColor(R.color.gold));
}
}
}
});