如何检查一行按钮中是否至少有一个 ToggleButton 被选中?

How can I check if at least one ToggleButton has been Checked in a row of Buttons?

我正在创建一个应用程序,该应用程序具有集成的 GAD 测试 功能(用于计算和测量用户压力水平的自我测试)。这是它的样子:

它由一个Table和多行ToggleButtons组成。这是其中 1 个按钮的代码,例如:

<ToggleButton
    android:id="@+id/row1_btn4"
    android:layout_width="200px"
    android:layout_height="60dp"
    android:layout_gravity="center_horizontal"
    android:background="@drawable/button_border"
    android:gravity="center"
    android:paddingStart="10px"
    android:paddingEnd="10px"
    android:scaleX="0.5"
    android:scaleY="0.65"
    android:textColor="@color/white"
    android:textOff="   "
    android:textOn="✓"
    android:textSize="28sp" />

这是检查按钮是否被选中的代码:

row1_btn4.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            gadpoints += 3;
            ((DataSite) getActivity().getApplication()).setGadPoints(gadpoints);
        } else if (!isChecked) {
            gadpoints -= 3;
            ((DataSite) getActivity().getApplication()).setGadPoints(gadpoints);
        } else {
            gadpoints += 0;
            ((DataSite) getActivity().getApplication()).setGadPoints(gadpoints);
        }
    }
});

一切正常,如果 选中 切换按钮,用户将获得给定的分数。但是,我想实现两件事:

a) 使每行1个按钮可以被选中,并防止用户在他/她已经选中1个的情况下选中同一行中的另一个按钮

b) 检查一行按钮none是否被检查,如果是,通知用户

我想不出一个可行的解决方案,因为我基本上是在检查按钮是否未被选中,但话又说回来,其中一些按钮本应被取消选中。有什么想法吗?

不使用切换按钮,而是为每一行使用 Radio Group。 然后您可以为单选按钮设计一个自定义可绘制对象,使它们看起来像您当前拥有的那样。

使用这个创建自定义按钮

<?xml version="1.0" encoding="utf-8"?>
<item android:state_checked="false" android:drawable="@drawable/ic_box"/>
<item android:state_checked="true" android:drawable="@drawable/ic_check"/>

您可以在 android studio 的资源管理器中获取 Box 和 Check drawable。

您可以使用 RadioGroup 管理每行只选择一个条目。要在未选择任何内容的情况下启动 RadioGroup,您可以对其调用 clearCheck()

要确保在他们单击“提交”时在所有行中都进行了选择,您可以在每个 group/row 上调用 getCheckedRadioButtonId(),如果没有任何内容,它将 return -1已选中。

如果您想自定义单选按钮的外观,有很多示例可以说明如何做到这一点 here

这是 onCreate 中的示例:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    List<RadioGroup> rows = Arrays.asList(
        findViewById(R.id.row1),
        findViewById(R.id.row2)
    );

    // Start out with all buttons un-checked
    for(RadioGroup row : rows) {
        row.clearCheck();
    }

    // make a list of button IDs for each row to 
    // simplify calculating the score
    List<List<Integer>> rowIds = Arrays.asList(
        Arrays.asList(R.id.row1_btn1, R.id.row1_btn2, R.id.row1_btn3, R.id.row1_btn4),
        Arrays.asList(R.id.row2_btn1, R.id.row2_btn2, R.id.row2_btn3, R.id.row2_btn4)
    );

    Button submit = findViewById(R.id.submit);

    submit.setOnClickListener(v -> {
        // check that all rows have selections
        boolean missing_values = false;
        for(RadioGroup row : rows) {
            // This will be -1 if nothing was selected
            if( row.getCheckedRadioButtonId() == -1 ) {
                missing_values = true;
            }
        }

        if( missing_values ) {
            Toast.makeText(this, "Missing entries on some rows", Toast.LENGTH_LONG).show();
        }
        else {
            // handle the result - add up scores or whatever is needed and send the data
            // to the model
            int score = 0;
            for(int r = 0; r < rows.size(); ++r) {
                int sel = rows.get(r).getCheckedRadioButtonId();
                score += rowIds.get(r).indexOf(sel);
            }
            Toast.makeText(this, "All rows selected - score = " + score, Toast.LENGTH_LONG).show();
        }
    });
}

以及随之而来的XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/row1_title"
        android:text="Row 1"
        android:layout_margin="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/row1"
        app:layout_constraintBottom_toBottomOf="@id/row1"/>

    <RadioGroup
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/row1"
        android:orientation="horizontal"
        app:layout_constraintStart_toEndOf="@id/row1_title"
        app:layout_constraintTop_toTopOf="parent">

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row1_btn1"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row1_btn2"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row1_btn3"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row1_btn4"/>

    </RadioGroup>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/row2_title"
        android:text="Row 2"
        android:layout_margin="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/row2"
        app:layout_constraintBottom_toBottomOf="@id/row2"/>

    <RadioGroup
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/row2"
        android:orientation="horizontal"
        app:layout_constraintStart_toEndOf="@id/row2_title"
        app:layout_constraintTop_toBottomOf="@id/row1">

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row2_btn1"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row2_btn2"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row2_btn3"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/row2_btn4"/>

    </RadioGroup>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Submit"
        android:id="@+id/submit"
        android:layout_margin="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/row2"
        />


</androidx.constraintlayout.widget.ConstraintLayout>