【问题标题】:Implement radio/checkbox logic to custom widgets为自定义小部件实现单选/复选框逻辑
【发布时间】:2021-10-13 12:25:06
【问题描述】:

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

这是我尝试在 Flutter 中重新创建的 android 实现:

我尝试使用带有 RadioListTiles 的 GridView,我想我可以用我自己的小部件替换 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;
            });
          },
        );
      },
    );
  }
}

导致:

我想尽可能地遵循最“Fluttery”的方式。 您认为我的最佳诉讼理由是什么?

【问题讨论】:

    标签: android gridview dart flutter radio-button


    【解决方案1】:

    这对我有用。

    为了模仿单选按钮的行为,我使用了“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))))
                            ]),
    

    结果如下所示

    【讨论】:

    • 看起来不错。你有最终结果的截图吗?我没有资产来复制代码,也没有时间运行它,但如果你能提供满足标准的屏幕截图或 gif,我很乐意为你提供这个问题的“正确答案”标记 :) 明智的代码它看起来很简单,但我自己没有使用过这个小部件,所以我想要一个图形表示。
    • 谢谢!我编辑了我的答案。添加了我的模拟器屏幕记录。
    • 太棒了!我现在也在开发一个宠物应用程序:)
    【解决方案2】:

    我也遇到了同样的问题,但颤振似乎没有提供任何这样的小部件。尝试使用第三方插件自定义收音机。

    https://pub.dev/packages/custom_radio

    【讨论】:

      【解决方案3】:

      尝试使用 FilterChip 和 ChoiceChip 小部件。 FilterChip 将实现复选框逻辑(多选),而 ChoiceChip 的行为类似于单选按钮。这两个小部件都允许您使用自定义小部件来适应您的用户界面。

      【讨论】:

        【解决方案4】:

        我为此目的创建了这个包。去看看这个。 Group radio button plugin

        https://github.com/Dineth95/radio_grouped_buttons

        Container(
                        padding: EdgeInsets.all(10),
                        width: MediaQuery.of(context).size.width,
                        height: 160,
                        child: CustomRadioButton(
                          buttonLables: buttonList,
                          buttonValues: buttonList,
                          radioButtonValue: (value)=>print(value),
                          horizontal: true,
                          enableShape: true,
                          buttonSpace: 5,
                          buttonColor: Colors.white,
                          selectedColor: Colors.cyan,
                        ),
                      ),
        

        Using this widget you can do anything you want

        【讨论】:

        • 看起来很可爱。下次我遇到需要单选按钮时会检查一下。你也可以选择多个框吗?
        • 作为第一个版本,我只添加了收音机功能。我将在未来添加该功能。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多