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

问题描述

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

到目前为止,我所能做的就是创建一排“容器行”窗口小部件,这些窗口小部件可以在点击时改变颜色,但是彼此独立地起作用。也就是说,用户可能单击多个选择,这很不好。我需要一些有关如何突破功能的新建议,在该功能下,只能选择一个容器,而所选的值将被传递出去。

干杯, 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),label: 'B',label: 'C',\],);
  }
}

Result

解决方法

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

  1. 简单的

因此Flutter提供了一个名为 ToggleButton 的小部件,该小部件可以满足上述所有需求。请遵循this文档,以获取有关此小部件的更多信息。

您可以在切换按钮的小部件列表中添加自定义的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',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:)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...