flutter - 如何在一定时间内执行动画
问题描述
代码如下(为了便于阅读,省略了一些函数)
RandomData() 为彩虹色动画提供数据点,而 mainBarData 表示固定条...
目前,当按下播放按钮时,isPlaying 变量变为 true,触发 refreshState() 以彩虹色为条中的随机数据设置动画,直到 isPlaying 变回 false。
我想要的 UI 是从没有条形开始的初始图形(检查 initData()),然后当按下播放按钮时,动画随机数据显示 1 秒,然后显示 mainBarData。
我怎样才能做到这一点?我的方法是实现一个以值 0 开头的计数器,当单击按钮时,它会递增到 1。然后,计数器 == 0 : BarGraph(initData()) : BarChart( isPlaying ?// 做点什么
但我想不出更多。有人可以帮忙吗?谢谢你。
import 'dart:async';
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class LeftoverBarchart extends StatefulWidget {
final List<Color> availableColors = [
Colors.purpleAccent,
Colors.yellow,
Colors.lightBlue,
Colors.orange,
Colors.pink,
Colors.redAccent,
];
@override
State<StatefulWidget> createState() => LeftoverBarchartState();
}
class LeftoverBarchartState extends State<LeftoverBarchart> {
final Color barBackgroundColor = const Color(0xff72d8bf);
final Duration animDuration = const Duration(milliseconds: 250);
int touchedIndex = -1;
bool isPlaying = false;
@override
Widget build(BuildContext context) {
int counter = 0;
return AspectRatio(
aspectRatio: 1,
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)),
color: const Color(0xff81e5cd),
child: Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
'Mingguan',
style: TextStyle(color: const Color(0xff0f4a3c), fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 4,
),
Text(
'Grafik konsumsi kalori.',
style: TextStyle(color: const Color(0xff379982), fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 38,
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child:
BarChart(
isPlaying ? randomData() : mainBarData(),
swapAnimationDuration: animDuration,
),
),
),
const SizedBox(
height: 12,
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.topRight,
child: IconButton(
icon: Icon(
isPlaying ? Icons.pause : Icons.play_arrow,
color: const Color(0xff0f4a3c),
),
onPressed: () {
if (counter == 0) {
counter = 1;
}
setState(() {
isPlaying = !isPlaying;
if (isPlaying) {
refreshState();
}
});
},
),
),
)
],
),
),
);
}
List<BarChartGroupData> showingGroups() => List.generate(7, (i) {
switch (i) {
case 0:
return makeGroupData(0, 5, isTouched: i == touchedIndex);
case 1:
return makeGroupData(1, 6.5, isTouched: i == touchedIndex);
case 2:
return makeGroupData(2, 5, isTouched: i == touchedIndex);
case 3:
return makeGroupData(3, 7.5, isTouched: i == touchedIndex);
case 4:
return makeGroupData(4, 9, isTouched: i == touchedIndex);
case 5:
return makeGroupData(5, 11.5, isTouched: i == touchedIndex);
case 6:
return makeGroupData(6, 6.5, isTouched: i == touchedIndex);
default:
return throw Error();
}
});
BarChartData initData() {
return BarChartData(
barTouchData: BarTouchData(
enabled: false,
),
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
showTitles: true,
getTextStyles: (context, value) => const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14),
margin: 16,
getTitles: (double value) {
switch (value.toInt()) {
case 0:
return '월';
case 1:
return '화';
case 2:
return '수';
case 3:
return '목';
case 4:
return '금';
case 5:
return '토';
case 6:
return '일';
default:
return '';
}
},
),
leftTitles: SideTitles(
showTitles: false,
),
topTitles: SideTitles(
showTitles: false,
),
rightTitles: SideTitles(
showTitles: false,
)),
borderData: FlBorderData(
show: false,
),
barGroups: List.generate(7, (i) {
switch (i) {
case 0:
return makeGroupData(0, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
case 1:
return makeGroupData(1, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
case 2:
return makeGroupData(2, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
case 3:
return makeGroupData(3, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
case 4:
return makeGroupData(4, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
case 5:
return makeGroupData(5, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
case 6:
return makeGroupData(6, 0, barColor: widget.availableColors[Random().nextInt(widget.availableColors.length)]);
default:
return throw Error();
}
}),
gridData: FlGridData(show: false),
);
}
Future<dynamic> refreshState() async {
setState(() {});
await Future<dynamic>.delayed(animDuration + const Duration(milliseconds: 50));
if (isPlaying) {
await refreshState();
}
}
}
[1]: https://i.stack.imgur.com/rv9lM.gif
解决方案
推荐阅读
- python - 使用来自 pytest 的 AdWordsClient 时出错 - 检测到递归(相同的本地人和位置)
- c++ - 使用标志 KMEANS_USE_INITIAL_LABELS 时是否有/如何解决 OpenCV C++ kmeans() 中的这个错误?
- spring - 具有安全默认登录成功重定向问题的 Spring Boot
- python - ModuleNotFoundError:没有名为“tensorflow”的模块。我应该怎么办?
- php - PHP页面刷新不保持变量值
- php - 如何在 oAuth PHP 系统中摆脱 Google Plus
- javascript - 芯片显示不一致
- php - 在我编辑输入时获取日期的值
- android - 扩展“AppCompatActivity”类不允许我使用 AppCompat 主题
- mysql - 如何在sql中同时计数和选择?