如何在Flutter中仅选择单选按钮的一组值?

Ter*_*ttu 6 radio-button dart flutter flutter-layout flutter-getx

我正在使用 Flutter-Dart-SQLite 开发测验应用程序。在这里,我使用 RadioListTile 来实现单选按钮功能。我将文本值从数组传递到 this StatefulWidget。这是我正在使用的代码,

    import 'package:flutter/material.dart';
    import 'package:get/get_state_manager/get_state_manager.dart';
    import 'package:loginform_validation_demo/QuizApp/controllers/question_controller.dart';
    import 'package:loginform_validation_demo/resource-file/constants.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    import 'package:flutter/src/material/radio_list_tile.dart';

    class OptionRadio extends StatefulWidget {
      final String text;
      final int index;
      final VoidCallback press;

      const OptionRadio({
        Key key,
        this.text,
        this.index,
        this.press,
      }) : super();

      @override
      OptionRadioPage createState() =>
          OptionRadioPage(this.text, this.index, this.press);
    }

    class OptionRadioPage extends State<OptionRadio> {
      final String text;
      int index;
      final VoidCallback press;
      QuestionController controllerCopy =QuestionController();

      int id = 1;
      int selectedButton = null;
      bool _isButtonDisabled;

      OptionRadioPage(this.text, this.index, this.press);

      @override
      void initState() {
        _isButtonDisabled = false;
      }

      int _selected = null;

      @override
      Widget build(BuildContext context) {
        return GetBuilder<QuestionController>(
            init: QuestionController(),
            builder: (qnController) {
              Color getTheRightColor() {
                if (qnController.isAnswered) {
                  if (index == qnController.selectedAns &&
                      qnController.selectedAns == qnController.correctAns) {

                    return kBlackColor;
                  } else if (index == qnController.selectedAns &&
                      qnController.selectedAns != qnController.correctAns) {
                    return kBlackColor;
                  }

                }
                return kBlackColor;
              }

              return InkWell(
                onTap: press,
                child: Container(
                  child: Row(
                    children: <Widget>[
                      Expanded(
                        child: Container(
                            // height: 60.0,
                            child: Theme(
                              data: Theme.of(context).copyWith(
                                  unselectedWidgetColor: Colors.grey,
                                  disabledColor: Colors.blue),
                              child: Column(children:
                              [
                                RadioListTile(
                                  title: Text(
                                    "${index + 1}. $text",
                                    style: TextStyle(
                                        color: getTheRightColor(), fontSize: 16),
                                    softWrap: true,
                                  ),
                                  /*Here the selectedButton which is null initially takes place of value after onChanged. Now, I need to clear the selected button when other button is clicked */
                                  groupValue: selectedButton,
                                  value: index,
                                  activeColor: Colors.green,
                                  onChanged:
                                      (val) async {

                                    debugPrint(
                                        'Radio button is clicked onChanged $val');
                                    setState(() {
                                      debugPrint('Radio button setState $val');
                                      selectedButton = val;
                                      debugPrint('Radio button is clicked onChanged $index');
                                    
                                    });
                                    SharedPreferences prefs = await SharedPreferences.getInstance();
                                    prefs.setInt('intValue', val);
                                  },
                                  toggleable: true,
                                ),
                              ]
                              ),
                            )),
                      ),
                    ],
                  ),
                ),
              );
            });
      }

      @override
      State<StatefulWidget> createState() {
        throw UnimplementedError();
      }
    }

Run Code Online (Sandbox Code Playgroud)

这里,最初为 null 的 selectedButton 取代了 after 组值的值onChanged。现在,我需要在单击另一个按钮时清除所选按钮。

在此输入图像描述

我猜我在团体价值部分做错了什么。

我使用OptionRadio的部分,

class QuestionCardWidgetRadio extends StatelessWidget {
  OptionRadio optionRadio = OptionRadio();
  QuestionCardWidgetRadio({
    Key key,
    this.note,
    this.index,
    this.questionLength,
  }) : super(key: key);

  final BlazorQuiz note;
  final int index;
  final int questionLength;
  bool _isAnswered = false;
  bool get isAnswered => this._isAnswered;
  int selectedButton;

  @override
  Widget build(BuildContext context) {
    QuestionController _questionController =
        Get.put(QuestionController());
    debugPrint("Answer Print : ${note.Answer.split(",")}");
    return Container(
        margin: EdgeInsets.symmetric(horizontal: kDefaultPadding, vertical: 35),
        decoration: BoxDecoration(
          color: Colors.white,
        borderRadius: BorderRadius.circular(25),
        ),
        padding: EdgeInsets.all(kDefaultPadding),
    child: SingleChildScrollView(
    scrollDirection: Axis.vertical,
        child: Column(
          children: [
            ...List.generate(
              note.Answer.split(",").length,
              (index) => OptionRadio(
                index: index,
                text: note.Answer.split(",")[index],
                press: (val) => setState(() {
                  selectedButton = int.parse(val.toString());
                  print("$selectedButton");
                }),
                selectedButton: selectedButton,
                // press:
                //       () =>{
                //   _isAnswered = true,
                //   _questionController.checkAns(note, index),
                //     selectedButton,
                // }
              ),

            SingleChildScrollView(
              scrollDirection: Axis.vertical,
              child: TextButton(
                onPressed: () async {
                  debugPrint("Clicked options : ${note.Answer.isNotEmpty} isAnswered: $isAnswered");
                  debugPrint('Check Index : ${index} check quiz model Lenght : ${QuizModel.question.length} check note Id : ${note.Id}');
                  if(index+1 == questionLength){
                    // score screen
                    debugPrint('Navigate to score screen');
                    Text(
                      "Submit",
                      style: Theme.of(context)
                          .textTheme
                          .button
                          .copyWith(color: Colors.white),
                    );
                    _questionController.scoreNavigation(index, context);
                  }
                  else{
                    if (note.Answer.isNotEmpty == !isAnswered) {
                      debugPrint('Clicked RadioBtn ${optionRadio.index}');
                      SharedPreferences prefs = await SharedPreferences.getInstance();
                      //Return int
                      int intValue = prefs.getInt('intValue');
                      debugPrint('Int value from sharedPrefs: $intValue');
                      _questionController.nextQuestion(note,intValue,"","",[]);
                      prefs.remove("intValue");
                    }else{
                      debugPrint('Click proper option for Radio');
                    }
                  }
                },

                child: Container(
                  width: double.infinity,
                  alignment: Alignment.center,
                  padding: EdgeInsets.all(kDefaultPadding * 0.75),
                  margin: EdgeInsets.all(37),
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(10)),
                      color: Color(ColorData.button)
                  ),
                  child: Text(
                    "Next Question",
                    style: Theme.of(context)
                        .textTheme
                        .button
                        .copyWith(color: Colors.white),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  setState(Null Function() param0) {}
}
Run Code Online (Sandbox Code Playgroud)

我从数组中获取值,其中选项以逗号分隔。“答案”:“男、女”

Diw*_*nsh 1

发生这种情况是因为您正在groupValue为每个单选按钮定义单独的按钮。不是selectedButton为每个按钮定义字段,而是在调用它的文件中定义一次widget并传递value它, constructor 如下代码所示:

class OptionRadio extends StatefulWidget {
  final String text;
  final int index;
  final ValueChanged<Object> press;
  final int selectButton;

  const OptionRadio({
    Key key,
    this.text,
    this.index,
    this.press, 
    this.selectButton,
  }) : super();

  @override
  OptionRadioPage createState() =>
      OptionRadioPage(this.text, this.index, this.press);
}
Run Code Online (Sandbox Code Playgroud)

value并将其使用press到您的单选按钮,如下所示:

                RadioListTile(
                              title: Text(
                                "${index + 1}. $text",
                                style: TextStyle(
                                    color: Colors.green, fontSize: 16),
                                softWrap: true,
                              ),
                              groupValue: widget.selectButton,
                              value: index,
                              activeColor: Colors.green,
                              onChanged: widget.press,
                            )
Run Code Online (Sandbox Code Playgroud)

也可以ValueChanged(Object)代替VoidCallBack

final ValueChanged<Object> press;
Run Code Online (Sandbox Code Playgroud)

并在那里传递一个适当的函数,例如:

OptionRadio(
                        text: "abc",
                        index: index,
                        press: (val) => setState(() {
                          selectButton = int.parse(val.toString());
                          print("$selectButton");
                        }),
                        selectButton: selectButton,
                      )
Run Code Online (Sandbox Code Playgroud)