如何实现Flutter Checkbox Stepper?

时间:2019-06-01 14:22:44

标签: flutter dart

我正在尝试实现以下布局

enter image description here

我尝试使用Stepper,但是并没有真正解决我的问题,所以我尝试使用香草dart代码本身

Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Checkbox(value: true, onChanged: (value) {}),
              Text("Complaint Received"),
            ],
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 20,
            ),
            child: Container(
              padding: const EdgeInsets.all(0),
              width: 2,
              height: 80,
              color: Colors.black,
            ),
          ),
          Row(
            children: <Widget>[
              Checkbox(value: true, onChanged: (value) {}),
              Text("Complaint Received"),
            ],
          ),
          Container(
            width: 2,
            height: 10,
            color: Colors.black,
          ),
          Row(
            children: <Widget>[
              Checkbox(value: true, onChanged: (value) {}),
              Text("Complaint Received"),
            ],
          ),
          Container(
            width: 2,
            height: 10,
            color: Colors.black,
          ),
          Row(
            children: <Widget>[
              Checkbox(value: true, onChanged: (value) {}),
              Text("Complaint Received"),
            ],
          ),
          Container(
            width: 2,
            height: 10,
            color: Colors.black,
          ),
        ],
      ),

以下是我实现的ui

enter image description here

我不明白为什么前两行和容器之间会有填充

1 个答案:

答案 0 :(得分:1)

在Flutter中,复选框不是像我们习惯的StatelessWidget那样的纯窗口小部件。

Checkbox绘制边界,带有圆形边缘的框,并通过RenderObject的{​​{1}}方法对自身进行'check'标记,有点像HTML5 Canvas(如果您熟悉的话) )。

这个事实使得很难自定义Flutter复选框,甚至更改诸如琐事之类的琐碎内容。


我的解决方案无法以您尝试的方式解决您的问题,但确实提供了一个极好的视图,就像您想要实现的那样。

paint

简而言之:

  • final double barsHeight = 40.0; final double barsWidth = 3.0; final Color inactiveBarColor = Colors.grey; final Color activeBarColor = Colors.blue; Map<String, bool> steps = { "Complaint Received": true, "Engineer Assigned": true, "Engineer On the way": false, "Complaint Done": false, }; @override Widget build(BuildContext context) { double rowPadding = (barsHeight - kRadialReactionRadius) / 2; double _barHeight = barsHeight; if (rowPadding < 0) { rowPadding = 0; _barHeight = kRadialReactionRadius; } return Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: Stack(fit: StackFit.loose, children: <Widget>[ Positioned( left: kRadialReactionRadius - barsWidth / 2, top: kRadialReactionRadius + rowPadding, bottom: kRadialReactionRadius + rowPadding, width: barsWidth, child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: List.generate(steps.length - 1, (i) => Container( margin: EdgeInsets.symmetric(vertical: kRadialReactionRadius / 2 - 2), height: _barHeight + 4, color: steps.values.elementAt(i) && steps.values.elementAt(i + 1) ? activeBarColor : inactiveBarColor, ) )) ), Theme( data: Theme.of(context).copyWith(disabledColor: inactiveBarColor, unselectedWidgetColor: inactiveBarColor), child: Column(mainAxisSize: MainAxisSize.min, children: steps.keys.map((key) => Padding( padding: EdgeInsets.symmetric(vertical: rowPadding), child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Checkbox( value: steps[key], onChanged: steps[key] ? (_) {} : null, activeColor: activeBarColor, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ), Text(key), ]) ) ).toList()) ) ]), ); } 使用Checkbox常量作为其大小和填充。这样便可以知道其确切大小,现在我们可以在每个复选框行之间绘制条形。
  • 使用kRadialReactionRadius,在带有复选框的Column下方绘制竖线。
  • 复选框的默认边框颜色被Stack小部件覆盖。

要更改复选框状态-只需修改Theme变量中的值。例如

steps

最终结果:

final result

让我知道这是否有帮助。