flutter - Flutter中如何实现多个倒计时进度条?
问题描述
如何在顶部实现 instagram 的故事进度条。如果存在多个故事,则为多个栏,如果只有一个则只有一个栏。一个10秒的计时器。到目前为止我所做的有点工作,但是当有 2 个或更多快照时它不起作用。
代码
Container(
height: 30,
margin: EdgeInsets.only(top: 50.0),
child: CustomPaint(
foregroundPainter: ProgressPainter(value: (this._totalTime) / 10.0 / widget.posts.length),
),
)
我尝试将它放入列表视图,但它有点不起作用。
更新:
我想出了一个“Row.builder” hack,但我怎样才能为进度设置动画呢?我使用倒计时作为计时器解决方案,我可以在计时器结束时更改快照,但进度条正确更新是问题所在。
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(widget.posts.length, (index) {
if (this._index == index) {
return Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
height: 30,
child: CustomPaint(
foregroundPainter: ProgressPainter(value: this._countDown.remainingTime.inSeconds / 10.0),
),
),
);
} else {
return Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
height: 30,
child: CustomPaint(
foregroundPainter: ProgressPainter(value: 0.0),
),
),
);
}
}).reversed.toList(),
)
注意:我有进度条工作的效果,但只有一个。我有 2 个帖子,但只有一个进度条有效,另一个保持 0。
解决方案
解决了。
倒计时:
int _index = 0;
CountDown _countDown;
StreamSubscription _countDownSubscription;
@override
void initState() {
super.initState();
this._initTimer();
}
_initTimer() {
if (mounted)
setState(() {
this._countDown = CountDown(Duration(seconds: widget.posts[this._index].timer));
this._countDown.remainingTime = Duration(seconds: widget.posts[this._index].timer);
this._countDownSubscription = this._countDown.stream.listen(null);
});
this._countDownSubscription.onData((d) {
setState(() {}); // Updates the UI to animate the progress bar
});
this._countDownSubscription.onDone(() {
if (widget.posts.length == this._index + 1) {
Navigator.of(context).pop();
} else {
if (mounted)
setState(() {
this._index++;
this._initTimer();
});
}
});
}
进度条:
class ProgressPainter extends CustomPainter {
final double value;
ProgressPainter({this.value});
Paint backgroundPaint = Paint()
..color = Colors.white
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..strokeWidth = 10;
Paint valuePaint = Paint()
..color = Colors.deepPurple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..strokeWidth = 10;
@override
void paint(Canvas canvas, Size size) {
Path backgroundPath = Path();
Path valuePath = Path();
backgroundPath.moveTo(0, size.height / 2);
backgroundPath.lineTo(size.width, size.height / 2);
valuePath.moveTo(0, size.height / 2);
valuePath.lineTo(size.width * this.value, size.height / 2);
canvas.drawPath(backgroundPath, backgroundPaint);
canvas.drawPath(valuePath, valuePaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
进度条的动态数量:
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(widget.posts.length, (index) {
if (this._index == index) { // Current active post
return Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: CustomPaint(
foregroundPainter: ProgressPainter(value: this._countDown.remainingTime.inSeconds / 10.0),
),
),
);
} else if (this._index > index) { // when it's done
return Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: CustomPaint(
foregroundPainter: ProgressPainter(value: 0.0),
),
),
);
} else { // When it's next
return Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: CustomPaint(
foregroundPainter: ProgressPainter(value: 1.0),
),
),
);
}
}).reversed.toList(),
)
如果你们都有更好、更简单的解决方案,我完全赞成。
推荐阅读
- c++ - C++ - 创建一个 2D 复制构造函数
- angular - @firebase/database:用户回调抛出异常。TypeError:无法读取未定义的属性“myID”
- javascript - 将 Map 转换为常规对象
- javascript - 传递键值时返回未定义的Javascript函数
- python - 如何在 django 中使用 html 输入表单
- ruby-on-rails - Minitest Fixture 出现错误:找不到具有 'id'= 的用户
- java - SpringBoot 找不到 Mongo Repository
- firebase - Firebase:删除所有经过身份验证的用户
- javascript - eslint package.json“解析json失败”错误
- android - 如何修复 CSS 在桌面上的 Chrome 移动模拟器和移动设备上的实际 Chrome 之间的行为不一致?