You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:35:22