繁体   English   中英

Flutter:来自小部件列表的自定义多项选择行

[英]Flutter: Custom Multiple Choice Row from List of Widgets

我正在尝试从容器小部件列表(包装在 GestureDetector 中用于 onTap)构建一个多选 Row。 当用户单击行中的容器小部件之一时,该容器小部件会更改颜色(变为蓝色)以反映用户的选择。 如果用户随后点击行中的不同容器小部件,该小部件会更改颜色以反映用户的选择,而所有其他小部件将重置为初始颜色(白色)。 此外,用户的选择(索引?)必须是可检索的。

到目前为止,我所能做的就是创建一排容器小部件,这些小部件在点击时改变颜色,但彼此独立运行。 也就是说用户可能会点击多选,这是不好的。 我需要一些关于如何突破到下一级别功能的建议,在该级别只能选择一个容器并传递所选值。

干杯,T

//choice button
class ChoiceButton extends StatefulWidget {
  final String label;
  final bool isPressed;

  const ChoiceButton({
    Key key,
    this.isPressed = false,
    this.label,
  }) : super(key: key);

  @override
  _ChoiceButtonState createState() => _ChoiceButtonState();
}

class _ChoiceButtonState extends State<ChoiceButton> {
  bool _isPressed;

  @override
  void initState() {
    super.initState();
    _isPressed = widget.isPressed;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _isPressed = !_isPressed;
        });
      },
      child: Container(
        height: 80,
        width: 80,
        decoration: BoxDecoration(
          color: _isPressed ? Colors.blue : Colors.transparent,
          border: Border.all(
            color: Colors.blue,
            width: 80 * 0.05,
          ),
        ),
        child: Center(
          child: Text(
            widget.label,
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.bold,
              color: _isPressed ? Colors.white : Colors.blue,
            ),
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );
  }
}

//choice row
class ChoiceRow extends StatefulWidget {
  @override
  _ChoiceRowState createState() => _ChoiceRowState();
}

class _ChoiceRowState extends State<ChoiceRow> {
  bool isPressed = false;
  String classChoice = '';

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: \[
        SizedBox(width: 30),
        ChoiceButton(
          isPressed: isPressed,
          label: 'A',
        ),
        SizedBox(width: 10),
        ChoiceButton(
          isPressed: isPressed,
          label: 'B',
        ),
        SizedBox(width: 10),
        ChoiceButton(
          isPressed: isPressed,
          label: 'C',
        ),
      \],
    );
  }
}

结果

我为此提供了两个答案......使用您喜欢的任何一个。

  1. 最简单的一个

因此 Flutter 提供了一个名为ToggleButton的小部件,它将满足上述所有需求。 按照文档了解有关此小部件的更多信息。

您可以在切换按钮的小部件列表中添加自定义的 ChoiceButton 设计,通过一些调整,您也可以实现您的 ChioceRow 设计。

  1. 现在,如果您喜欢从头开始制作所有内容(例如我 :P),那么我对您上面提供的代码进行了一些更改,这将满足您的所有需求。 下面是编辑后的代码。
class ChoiceRow extends StatefulWidget {
  @override
  _ChoiceRowState createState() => _ChoiceRowState();
}

class _ChoiceRowState extends State<ChoiceRow> {

  List<bool> isPressedList = [false,false,false];

  String classChoice = '';

  @override
  Widget build(BuildContext context) {

    print("Status L $isPressedList");

    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        SizedBox(width: 30),
        GestureDetector(
          onTap: (){
            print("Hello");
            setState(() {
              isPressedList[0] = true;
              isPressedList[1] = false;
              isPressedList[2] = false;
            });
          },
          child: ChoiceButton(
            isPressed: isPressedList[0],
            label: 'A',
          ),
        ),
        SizedBox(width: 10),
        GestureDetector(
          onTap: (){
            setState(() {
              isPressedList[0] = false;
              isPressedList[1] = true;
              isPressedList[2] = false;
            });
          },
          child: ChoiceButton(
            isPressed: isPressedList[1],
            label: 'B',
          ),
        ),
        SizedBox(width: 10),
        GestureDetector(
          onTap: (){
            setState(() {
              isPressedList[0] = false;
              isPressedList[1] = false;
              isPressedList[2] = true;
            });
          },
          child: ChoiceButton(
            isPressed: isPressedList[2],
            label: 'C',
          ),
        ),
      ],
    );
  }
}







class ChoiceButton extends StatelessWidget {

  final String label;
  final bool isPressed;

  ChoiceButton({this.label,this.isPressed});


  @override
  Widget build(BuildContext context) {
    return Container(
      height: 80,
      width: 80,
      decoration: BoxDecoration(
        color: isPressed ? Colors.blue : Colors.transparent,
        border: Border.all(
          color: Colors.blue,
          width: 80 * 0.05,
        ),
      ),
      child: Center(
        child: Text(
          label,
          style: TextStyle(
            fontSize: 12,
            fontWeight: FontWeight.bold,
            color: isPressed ? Colors.white : Colors.blue,
          ),
          textAlign: TextAlign.center,
        ),
      ),
    );
  }
}

变化 :

  1. 我制作了一个列表 (onPressedList),它跟踪切换按钮的当前状态(比如哪个是打开的,哪些是关闭的)。

  2. 我在 ChoiceRow 类中的按钮上移动了 GestureDetector 包装。 这是因为很难将 onTap 结果从 ChoiceButton 传递到 ChoiceRow。 (现在,如果您想要 Button 类本身中的手势检测器,那么您可以将列表设为全局或完全不同的静态值,以便可以正确访问它)

  3. 我将 ChoiceButton 类设为无状态,因为现在不需要保持它有状态。

我所做的两件事是添加一个列表来跟踪切换按钮的当前状态,当一个切换按钮处于活动状态时,所有其他按钮都将被停用。

现在它按照您上面提到的方式工作,您还可以通过“isPressedList”跟踪所有按钮的当前状态。

GLHF :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM