Flutter:如何修正屏幕填充动画方向,实现从上到下效果?
解决Flutter从上到下屏幕填充过渡动画的问题
要实现从上到下的屏幕填充动画,核心是让填充色的矩形从屏幕顶部开始,高度随动画值逐步增加,直到铺满整个屏幕。结合Flutter的坐标系(左上角为原点,Y轴向下),我们可以通过调整矩形的计算逻辑或动画方向来修正效果。
问题分析
你当前代码的逻辑本身是正确的(从顶部向下扩展矩形),但出现反向效果的原因通常有两个:
- 动画方向反向:
AnimationController使用了reverse()播放,导致动画值从1→0,矩形高度从满屏缩至0,视觉上呈现填充色从下往上消失。 - 颜色绘制顺序错误:若填充色与背景色的绘制顺序颠倒,也会导致视觉效果反向。
修正方案
方案1:确保动画正向播放
调整 AnimationController 使用 forward() 正向播放,让动画值从0→1,配合原有矩形逻辑即可实现正确效果:
// 在使用CustomPainter的Widget中 class _DemoWidgetState extends State<DemoWidget> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _animation; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(seconds: 2), ); // 动画值从0到1,正向过渡 _animation = Tween<double>(begin: 0, end: 1).animate(_controller); _controller.forward(); // 正向播放动画 } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return CustomPaint( painter: CustomTimePainter( animation: _animation, backgroundColor: Colors.white, color: Colors.deepPurple, ), ); } }
方案2:修改矩形计算逻辑(适配反向动画)
如果必须保留反向动画(值从1→0),可以调整矩形的底部位置计算,确保填充效果从上到下:
import 'dart:ui' as ui; import 'package:flutter/material.dart'; class CustomTimePainter extends CustomPainter { CustomTimePainter({ required this.animation, required this.backgroundColor, required this.color, }) : super(repaint: animation); final Animation<double> animation; final Color backgroundColor, color; @override void paint(Canvas canvas, Size size) { var paint = Paint()..color = backgroundColor; canvas.drawPaint(paint); // 适配反向动画:计算从0到size.height的填充高度 final fillBottom = ui.lerpDouble(0, size.height, 1 - animation.value)!; Rect fillRect = Rect.fromLTRB(0, 0, size.width, fillBottom); // 直接使用drawRect替代Path,更高效 canvas.drawRect(fillRect, paint..color = color); } @override bool shouldRepaint(CustomTimePainter old) { return animation.value != old.animation.value || color != old.color || backgroundColor != old.backgroundColor; } }
额外优化
代码中无需通过Path绘制矩形,直接使用canvas.drawRect()更高效,已在修正代码中调整。
内容的提问来源于stack exchange,提问作者pomoworko.com
相关产品推荐
相关产品推荐

