切换一个按钮并取消切换另一个按钮

Posted

技术标签:

【中文标题】切换一个按钮并取消切换另一个按钮【英文标题】:Toggle one button and untoggled other button 【发布时间】:2020-08-24 02:36:55 【问题描述】:

我正在学习 Kotlin,我正在尝试制作两个可以切换具有以下特征的按钮:

    按钮 1 以 toggled(true) 开头,按钮 2 以 unggled(false) 开头。 如果我单击未切换的按钮,他将变为已切换,而另一个未切换。 如果我单击切换的按钮,他将变为未切换,而另一个则切换。 如果一个按钮为真,则另一个为假。 切换按钮始终为黄色,另一个未切换按钮为白色。

按钮代码:

<ToggleButton
    android:id="@+id/button1"
    android:background="@color/yellow"
    android:text="ToggleButton"
    android:textOff="Ton"
    android:textOn="Ton"/>

<ToggleButton
    android:id="@+id/button2"
    android:background="@color/white"
    android:text="ToggleButton"
    android:textOff="Kg"
    android:textOn="Kg"/>

活动代码:

private val btn1 by lazy  findViewById<View>(R.id.button1) as ToggleButton 
private val btn2 by lazy  findViewById<View>(R.id.button2) as ToggleButton 

btn1.setOnClickListener
    btn1.setOnCheckedChangeListener  _, isChecked ->
        if (isChecked)  //if btn1 is true he is yellow and btn2 is false and he is white
            btn2.isChecked = false
            btn1.setBackgroundColor(Color.YELLOW)
            btnLoadModeFrac.setBackgroundColor(Color.WHITE)
         else  //if btn1 is false he is white and btn2 is true and he is yellow
            btn2.isChecked = true
            btn1.setBackgroundColor(Color.WHITE)
            btn2.setBackgroundColor(Color.YELLOW)
        
    

问题

这里的问题是,在第一次单击时,我可以同时切换按钮 1 和按钮 2(两者都是 true),即使我将一个设置为 false 而另一个设置为 true。之后,一切正常。

在调用函数之前,我尝试在我的活动中将按钮 1 设置为 true 并将按钮 2 设置为 false,但它也不起作用。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

我认为使用OnCheckedChangeListener 切换另一个按钮将是解决问题的困难方法,因为当其中一个按钮被切换时,它会想要切换另一个,从而使其想要切换其他,以此类推。

由于您正在更改颜色以匹配切换状态,因此使用样式来处理它会更合适和更健壮。像这样创建一个 StateListDrawable:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@color/yellow" android:state_checked="true"/>
  <item android:drawable="@color/white"/>
</selector>

并将其设置为布局文件中两个按钮的背景,而不是显式颜色。

您还需要将其中一个按钮设置为初始状态为选中:

android:checked="true"

让它们相互更改的简单方法是为它们各自提供一个单击侦听器来切换另一个按钮。

btn1.setOnClickListener  _ -> btn2.isChecked = !btn2.isChecked 
btn2.setOnClickListener  _ -> btn1.isChecked = !btn1.isChecked 

但在我看来,如果您需要这些元素保持同步,那么依靠 UI 元素来存储您的状态并不是一个好习惯。有一些 UI 行为可能很挑剔(例如双击启动 Activity 的按钮可以启动该 Activity 的两个副本的速度)。所以我会把你的状态保存在一个属性中。您可以使其可观察,因此每次更改它都会显式设置两个按钮的切换状态。

private val buttonState by Delegates.observable(true)  _, _, newState ->
    btn1.isChecked = newState
    btn2.isChecked = !newState


//...

val listener = View.OnClickListener  _ -> buttonState = !buttonState 
btn1.onClickListener = listener
btn2.onClickListener = listener

【讨论】:

【参考方案2】:

您需要将OnCheckedChangeListener 附加到btn1btn2。您仅将其附加到 OnCheckedChangeListener。另一个的逻辑需要稍有不同。要么这样,要么您可以创建一个通用的OnCheckedChangeListener,您可以将其附加到两个按钮,但是您需要确定单击了哪个按钮,以便您可以执行正确的逻辑。单击的View 作为参数传递给方法。

【讨论】:

以上是关于切换一个按钮并取消切换另一个按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何链接一组切换按钮,如单选按钮?

全选 |使用切换按钮取消选择所有复选框

切换开关 - 当我启用另一个按钮时禁用一个按钮

如何在fragment中点击按钮切换到另一个fragment中

UILabel 中的按钮/链接以切换到另一个 ViewController

取消选中单击时活动的 Angular Material 切换按钮