为自定义小部件实现单选/复选框逻辑

Joe*_*röm 5 android gridview radio-button dart flutter

我想创建两个小部件。两者都显示一个 2 列网格,其中带有可以选择/取消选择的按钮。一个应该具有单选逻辑(单选),而另一个应该具有复选框逻辑(多选)。

这是我试图在 Flutter 中重新创建的 Android 实现:

我尝试将 GridView 与 RadioListTiles 一起使用,认为我可以用自己的小部件替换 RadioButton 图标,同时保留逻辑。我看不出有什么办法可以做到这一点。我还意识到 Flutter 中的 GridView 不会自动换行它的子项,导致每个无线电图块仅占用整个单元格的前 10%。

这就是我现在所处的位置:

class RadioSelect extends StatefulWidget {
    final QuestionData question;

    RadioSelect({this.question});

    @override
    RadioSelectState createState() => RadioSelectState(question);
}

class RadioSelectState extends State<RadioSelect> {
  RadioSelectState(this._question);

  final QuestionData _question;
  final SliverGridDelegate delegate = 
    SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2);
  int _selectedIndex;

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: delegate,
      padding: EdgeInsets.all(0),
      itemCount: _question.selectOptions.length,
      itemBuilder: (context, index) {
        return RadioListTile(
          groupValue: _selectedIndex,
          title: Text(_question.selectOptions[index]),
          value: index,
          onChanged: (newIndex) {
           setState(() {
              _selectedIndex = newIndex;
            });
          },
        );
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

导致:

在此输入图像描述

我想尽可能遵循最“Fluttery”的方式。您认为我最好的行动理由是什么?

Mr *_*mit 2

这对我有用。

为了模仿单选按钮的行为,我使用了“ChoiceChip”。您可以在下面的代码中看到父小部件是一个“行”,但我认为“包装”作为父小部件可能最适合此用例。

“ChoiceChip”的适当形状可以帮助您根据需要塑造它。

 Row(  
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Expanded(
                              child: ChoiceChip(
                                  avatar: image.asset(
                                      "assets/left.png",
                                      matchTextDirection: false,
                                      width: 20.0),
                                  label: Text('LEFT',
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 20)),
                                  labelPadding:
                                      EdgeInsets.symmetric(horizontal: 50),
                                  selected: choice== 'left',
                                  onSelected: (bool selected) {
                                    setState(() {
                                      choice= selected ? 'left' : null;
                                    });
                                  },
                                  selectedColor: Color(0xFF0D47A1),
                                  shape: ContinuousRectangleBorder(
                                      borderRadius:
                                          BorderRadius.circular(5.0)))),
                          Expanded(
                              child: ChoiceChip(
                                  avatar: image.asset(
                                      "assets/right.png",
                                      matchTextDirection: false,
                                      width: 20.0),
                                  label: Text('RIGHT',
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 20)),
                                  labelPadding:
                                      EdgeInsets.symmetric(horizontal: 50),
                                  selected: choice== 'right',
                                  onSelected: (bool selected) {
                                    setState(() {
                                      choice= selected ? 'right' : null;
                                    });
                                  },
                                  selectedColor: Color(0xFF0D47A1),
                                  shape: ContinuousRectangleBorder(
                                      borderRadius:
                                          BorderRadius.circular(5.0))))
                        ]),
Run Code Online (Sandbox Code Playgroud)

结果看起来像这样

在此输入图像描述