我想实现一个开关按钮android.widget.Switch(可从API v.14获得)。
<Switch
android:id="@+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Switch" />
但我不确定如何为按钮添加事件监听器。它应该是一个“onClick”监听器吗?我怎么知道它是否“开启”了?
答案 0 :(得分:416)
Switch继承了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
}
});
答案 1 :(得分:46)
使用以下代码段通过XML将切换添加到布局:
<Switch
android:id="@+id/on_off_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="OFF"
android:textOn="ON"/>
然后在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);
}
});
答案 2 :(得分:18)
定义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>
然后创建一个活动
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
}
}
****
}
========对于以下API 14 ,请使用SwitchCompat =========
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>
活动
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
}
}
*****
}
答案 3 :(得分:9)
对于那些使用Kotlin的人,您可以为开关设置一个监听器(在这种情况下具有ID mySwitch
),如下所示:
mySwitch.setOnCheckedChangeListener { _, isChecked -> run {
// do whatever you need to do when the switch is toggled here
}
}
如果当前检查(ON)开关,则 isChecked
为真,否则为假。
答案 4 :(得分:5)
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>
在Activity类中,您可以通过两种方式进行编码。取决于您可以使用的代码。
第一种方式
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");
}
}
第二种方式
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");
}
}
});
}
}
答案 5 :(得分:1)
有两种方法,
使用xml onclick视图 如下所示以XML添加Switch:
<Switch
android:id="@+id/switch1"
android:onClick="toggle"/>
在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));
}
}
}
添加XML开关,如下所示:
在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));
}
}
}
});
答案 6 :(得分:1)
2020年9月-以编程方式回答
您可以通过编程的方式为Switch Widget和Material Design做到这一点:
Switch yourSwitchButton = findViewById(R.id.switch_id);
yourSwitchButton.setChecked(true); // true is open, false is close.
yourSwitchButton.setOnCheckedChangeListener((compoundButton, b) -> {
if (b){
//open job.
}
else {
//close job.
}
});
@canerkaseler
答案 7 :(得分:0)
您可以将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)}"
/>
答案 8 :(得分:0)
我的解决方案,使用SwitchCompat
和Kotlin。在我的情况下,仅当用户通过UI触发更改时,我才需要对更改做出反应。实际上,我的开关对LiveData
有反应,这使得setOnClickListener
和setOnCheckedChangeListener
都无法使用。 setOnClickListener
实际上对用户交互做出正确反应,但是如果用户在开关上拖动拇指则不会触发。如果以编程方式(例如,由观察者)切换了开关,则另一端的setOnCheckedChangeListener
也将被触发。现在,在我的情况下,该开关位于两个片段上,因此在某些情况下,onRestoreInstanceState会触发带有旧值的开关覆盖正确的值。
因此,我查看了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)
}
}
如何使用它:
实际的监听器接受带有代码的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)
}
)
为了完整起见,状态switchstate
(如果有)的观察者是这样的:
switchstate.observe(this, Observer {
myswitch.isChecked = it
})
答案 9 :(得分:0)
在科特林:
switch_button.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
// The switch enabled
text_view.text = "Switch on"
} else {
// The switch disabled
text_view.text = "Switch off"
}
}
答案 10 :(得分:0)
在“活动”类中
switch.setOnCheckedChangeListener((CompoundButton.OnCheckedChangeListener) (buttonView, isChecked) -> {
if (isChecked){
// your code
} else {
// your code
}
});
Switch小部件的布局
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:checked="true"
android:layoutDirection="ltr"/>