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

Toggle one button and untoggled other button

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

  1. 按钮 1 开始时为切换状态 (true),按钮 2 开始时未切换状态 (false)。
  2. 如果我点击未切换的按钮,他会切换,而另一个未切换。
  3. 如果我点击那个被切换的按钮,他变成未切换的,另一个被切换。
  4. 如果一个按钮为真,另一个为假。
  5. 切换按钮始终为黄色,另一个未切换按钮为白色。

按钮代码:

<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"/>

activity代码:

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。之后一切正常。

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

感谢您的帮助!

您需要将 OnCheckedChangeListener 附加到 btn1btn2。您只将它附加到 OnCheckedChangeListener。另一个的逻辑需要略有不同。或者,您可以创建一个通用的 OnCheckedChangeListener,您可以将其附加到两个按钮,但随后您需要确定单击了哪个按钮,以便执行正确的逻辑。单击的 View 作为参数传递给该方法。

我认为使用 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