flutter - Flutter Checkbox Stepper如何实现?
问题描述
我正在尝试实现以下布局
我尝试使用 Stepper,但它并没有真正解决我的问题,所以我尝试使用 vanilla 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
我不明白为什么前两行和容器之间有填充
解决方案
在 Flutter 中,复选框并不是StatelessWidget
我们习惯的那种纯粹的小部件。
Checkbox
RenderObject
通过'方法绘制它的边界、一个带有圆边的框和“复选”标记本身paint
,有点像 HTML5 Canvas(如果你熟悉的话)。
这一事实使得自定义 Flutter 复选框变得很困难,甚至改变了诸如围绕它的填充之类的琐碎的东西。
我的解决方案并没有以您尝试的方式解决您的问题,但它确实提供了一个很棒的视图,就像您想要实现的那样。
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
变量中的值。例如
setState(() {
steps[steps.keys.elementAt(/*checkbox index*/)] = true;
});
最后结果:
让我知道这是否有帮助。
推荐阅读
- php - 不能两次使用更新准备好的语句
- python - 出现“+”时如何取总和?
- java - 尝试使用 Java SDK 从 S3 存储桶下载文件,isStandardEndpoint 上出现空指针异常
- java - 使用 Spring Boot 应用程序作为 gradle 的依赖项
- google-apps-script - 在 Google Scripts EmbeddedColumnChartBuilder 中设置 Y 轴选项
- angular - 数字格式角管
- c - 如何修复c qsort函数中的“discard const”(数组是指针数组),可能与对指针的理解有关
- vb.net - 检查多个条件的条件?
- user-interface - 如何在 Ubuntu 服务器上设置 GUI 测试自动化
- python - 日期范围匹配函数 pandas