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

Flutter实现文本从屏幕左侧飞入居中动画的方法

Flutter实现依次飞入的文本动画

你可以通过两种方式实现这个需求:原生Flutter动画API(无需第三方包)或者使用专门的动画编排包简化开发。

一、原生实现(推荐,轻量可控)

利用AnimationController、Tween和SlideTransition组合,配合Future.delayed控制动画启动间隔,就能实现文本依次从左侧飞入中心的效果。

完整代码示例

import 'package:flutter/material.dart';

class FlyInTextPage extends StatefulWidget {
  const FlyInTextPage({super.key});

  @override
  State<FlyInTextPage> createState() => _FlyInTextPageState();
}

class _FlyInTextPageState extends State<FlyInTextPage> with TickerProviderStateMixin {
  late final List<AnimationController> _controllers;
  late final List<Animation<Offset>> _animations;
  final List<String> _texts = ["第一段文本", "第二段文本", "第三段文本"];

  @override
  void initState() {
    super.initState();
    // 初始化3个动画控制器,每个控制一段文本的动画
    _controllers = List.generate(3, (index) => AnimationController(
      duration: const Duration(milliseconds: 800),
      vsync: this,
    ));

    // 定义从左侧(-1,0)到中心(0,0)的位移动画
    _animations = _controllers.map((controller) => Tween<Offset>(
      begin: const Offset(-1.0, 0.0),
      end: Offset.zero,
    ).animate(CurvedAnimation(
      parent: controller,
      curve: Curves.easeOut,
    ))).toList();

    // 依次启动动画,间隔1秒
    _startAnimations();
  }

  void _startAnimations() async {
    await Future.delayed(Duration.zero); // 确保Widget已完成挂载
    _controllers[0].forward();
    await Future.delayed(const Duration(seconds: 1));
    _controllers[1].forward();
    await Future.delayed(const Duration(seconds: 1));
    _controllers[2].forward();
  }

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    for (var controller in _controllers) controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List.generate(3, (index) {
            return SlideTransition(
              position: _animations[index],
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 16.0),
                child: Text(_texts[index], style: const TextStyle(fontSize: 24)),
              ),
            );
          }),
        ),
      ),
    );
  }
}

关键说明

  • SlideTransition:负责将位移动画应用到文本组件,实现飞入效果
  • AnimationController:控制动画的启动、停止及持续时长
  • Future.delayed:精准控制每段文本动画的启动间隔

二、第三方包实现(复杂场景推荐)

如果需要编排更复杂的序列动画,可以使用flutter_sequence_animation包,它能更直观地定义多动画的时间线。

步骤1:添加依赖

在pubspec.yaml中加入:

dependencies:
  flutter_sequence_animation: ^2.0.0

步骤2:完整代码示例

import 'package:flutter/material.dart';
import 'package:flutter_sequence_animation/flutter_sequence_animation.dart';

class SequenceFlyInPage extends StatefulWidget {
  const SequenceFlyInPage({super.key});

  @override
  State<SequenceFlyInPage> createState() => _SequenceFlyInPageState();
}

class _SequenceFlyInPageState extends State<SequenceFlyInPage> with TickerProviderStateMixin {
  late final AnimationController _controller;
  late final SequenceAnimation _sequenceAnimation;
  final List<String> _texts = ["第一段文本", "第二段文本", "第三段文本"];

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 4), // 总时长覆盖所有动画周期
      vsync: this,
    );

    // 编排序列动画:依次定义每段文本的动画时间区间
    _sequenceAnimation = SequenceAnimationBuilder()
        .addAnimatable(
          animatable: Tween<Offset>(begin: const Offset(-1,0), end: Offset.zero),
          from: const Duration(seconds: 0),
          to: const Duration(milliseconds: 800),
          tag: "text0",
          curve: Curves.easeOut,
        )
        .addAnimatable(
          animatable: Tween<Offset>(begin: const Offset(-1,0), end: Offset.zero),
          from: const Duration(seconds: 1),
          to: const Duration(milliseconds: 1800),
          tag: "text1",
          curve: Curves.easeOut,
        )
        .addAnimatable(
          animatable: Tween<Offset>(begin: const Offset(-1,0), end: Offset.zero),
          from: const Duration(seconds: 2),
          to: const Duration(milliseconds: 2800),
          tag: "text2",
          curve: Curves.easeOut,
        )
        .animate(_controller);

    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SlideTransition(
              position: _sequenceAnimation["text0"]!.value,
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 16),
                child: Text(_texts[0], style: const TextStyle(fontSize:24)),
              ),
            ),
            SlideTransition(
              position: _sequenceAnimation["text1"]!.value,
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 16),
                child: Text(_texts[1], style: const TextStyle(fontSize:24)),
              ),
            ),
            SlideTransition(
              position: _sequenceAnimation["text2"]!.value,
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 16),
                child: Text(_texts[2], style: const TextStyle(fontSize:24)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

总结

  • 简单场景:优先用原生API,无需额外依赖,性能更优
  • 复杂序列动画:使用flutter_sequence_animation简化时间线编排

内容的提问来源于stack exchange,提问作者Arjun Malhotra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:10:15