flutter - 具有渐变背景颜色的动画容器
问题描述
如何从下到上更改容器的背景颜色?当我使用渐变时,我不喜欢这种效果。我构建了第二个容器,但它不是动态的。
class MyCustomContainer extends StatefulWidget {
final Color backgroundColor;
final Color progressColor;
final double progress;
final double size;
const MyCustomContainer({
Key key,
this.backgroundColor = Colors.grey,
this.progressColor = Colors.red,
@required this.progress,
@required this.size,
}) : super(key: key);
@override
_MyCustomContainerState createState() => _MyCustomContainerState();
}
class _MyCustomContainerState extends State<MyCustomContainer> {
double _progress;
@override
void initState() {
super.initState();
_progress = widget.progress;
}
onPaint() {
setState(() {
if (_progress == 0) {
_progress = 1;
} else {
_progress = 0;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
height: widget.size,
width: widget.size,
child: Stack(
children: [
Container(
color: widget.backgroundColor,
child: Column(
children: [
Container(
height: widget.size * 0.3,
color: Colors.green,
),
Container(
height: widget.size * 0.7,
color: Colors.red,
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOutExpo,
height: widget.size * _progress,
child: Column(children: [
Container(
height: widget.size * 0.3,
color: Colors.red,
),
Container(
height: widget.size * 0.7,
color: Colors.green,
),
]),
),
),
Text('asdas'),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => onPaint(),
child: Icon(Icons.ac_unit),
),
);
}
}
我想要这种过渡,一遍又一遍地改变两个容器的颜色。如果状态发生变化,请进行转换,并在下一次迭代中更改颜色并再次播放。这是要模拟的动画。 视频动画
知道怎么做吗?
解决方案
有类似ColorTween
类的东西(https://api.flutter.dev/flutter/animation/ColorTween-class.html)
你可以谷歌一些教程如何做到这一点,有很多。
更新
如果您想将一个容器与另一个容器悬停,然后及时重新打开它,我会将两者都Containers
放入Stack widget
并将其中一个的初始高度设置Containers
为 0,并且只是设置动画高度。
更新 2
为了能够控制动画,您应该使用AnimationController
并且可以忘记使用AnimatedContainer
.
当我尝试如何重置AnimatedContainer
时,有一些技巧可以做到这一点。关键是设置回调onEnd
和内部将持续时间更改为1 milisecond
,恢复_progress
到初始值和setState
,在再次开始动画之前,您需要设置适当的持续时间。
void initState() {
super.initState();
_progress = 0;
}
onPaint() {
setState(() {
dynamicDuration = Duration(milliseconds: 2000);
if (_progress == 1) {
_progress = 0;
} else {
_progress = 1;
}
});
}
void resetAnim(){
setState((){
dynamicDuration = Duration(milliseconds: 1);
_progress = 0;
});
}
更新 3
为了能够循环它,您必须使用异步函数等到恢复到 A 点结束
void resetAnim() async {
setState((){
dynamicDuration = Duration(milliseconds: 1);
_progress = 0;
});
await new Future.delayed(const Duration(milliseconds : 50));
setState(() {
dynamicDuration = Duration(milliseconds: 2000);
_progress = 1;
});
这一切看起来有点棘手/肮脏,所以也许值得学习使用AnimationController
和/或TweenAnimationBuilder
推荐阅读
- javascript - 为什么我仍然收到“目标容器不是 DOM 元素”。在 ReactDom.render
- python-2.7 - Elasticsearch 返回错误的计数
- c# - ML.NET 算法正在评估有关乳腺癌的实例总是错误的
- swift - Swift 帮助从未来日期中提取月份值
- django - FileSystemStorage 不起作用,当上传 2 张图片时,返回 SuspiciousFileOperation 错误
- c# - 试图避免 c# Windows 应用程序中的循环依赖
- r - 如何在 R 中调试代码以使用 Dplyr 按组获取变量的标准差?
- python - 在未调用 Popup.open() 的方法中触发 Popup.dismiss() (kivy)
- javascript - 单击按钮后如何重置数据对象
- python - 在步骤函数中调用时如何返回 Python 粘合作业?