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

Flutter中Hero动画无法正常工作问题求助

Hero动画无法在Flutter启动页到主页过渡中正常工作的解决方案

我帮你排查了代码里的问题,Hero动画失效主要是这几个原因导致的:

  • 启动页里的Hero组件被Opacity包裹,而且Opacity的透明度绑定了一个正在运行的动画,这会干扰Hero框架对组件的识别和过渡逻辑
  • initState里的方法顺序搞反了,你先触发了导航逻辑,再初始化动画控制器,容易导致动画和导航的时序冲突
  • 虽然你两个页面的Hero标签完全一致(这点做得对),但启动页的层级结构可能影响Hero的上下文传递

修复方案和修改后的代码

1. 调整启动页代码

主要做了这几个改动:

  • 把Opacity移到Hero组件内部,直接作用在Image上,避免外层动画干扰Hero的过渡
  • 调整initState的方法顺序,先初始化动画控制器再触发导航
  • 加上了dispose方法销毁动画控制器,防止内存泄漏
  • 用pushReplacement代替push,因为启动页一般不需要返回,优化内存占用
import 'package:flutter/material.dart';
import 'home_page.dart';
import 'dart:async';

class Splash extends StatefulWidget {
  @override
  _SplashState createState() => _SplashState();
}

class _SplashState extends State<Splash> with SingleTickerProviderStateMixin {
  Animation<double> _mainLogoAnimation;
  AnimationController _mainLogoAnimationController;

  @override
  void initState() {
    super.initState();
    // 先初始化动画控制器,再启动导航逻辑
    _mainLogoAnimationController = AnimationController(
      duration: const Duration(milliseconds: 2500),
      vsync: this,
    );
    _mainLogoAnimation = CurvedAnimation(
      parent: _mainLogoAnimationController,
      curve: Curves.easeIn,
    );
    _mainLogoAnimationController.forward();
    goToHomePage();
  }

  Future goToHomePage() async {
    await Future.delayed(const Duration(milliseconds: 4000));
    // 用pushReplacement替代push,避免栈中保留启动页
    Navigator.of(context).pushReplacement(MaterialPageRoute(
      builder: (BuildContext context) => const HomePage(),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.black,
      child: Center(
        // 将Opacity放在Hero内部,只控制图片的透明度
        child: Hero(
          tag: 'tbh_logo',
          child: Opacity(
            opacity: _mainLogoAnimation.value,
            child: Image(
              image: const AssetImage('assets/images/tbh_main_logo.png'),
              width: 300.0,
            ),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 销毁动画控制器,防止内存泄漏
    _mainLogoAnimationController.dispose();
    super.dispose();
  }
}

2. 主页代码(仅做小优化)

主页的Hero部分没问题,我只是加了一些const关键字优化性能:

import 'package:flutter/material.dart';
import '../ui/drawer.dart';

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

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("The Barni House"),
        backgroundColor: Colors.black,
      ),
      drawer: const Drawer(child: MyDrawer()),
      body: const Center(
        child: Column(
          children: [
            Hero(
              tag: 'tbh_logo',
              child: Image(
                image: AssetImage('assets/images/tbh_main_logo.png'),
                width: 300.0,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

额外提示

  • 确保图片资源路径正确,否则Hero动画也会因为组件不匹配而失效
  • 如果还是有问题,可以尝试把启动页的Material换成Scaffold,保持和主页的根组件一致,有时候上下文不一致也会影响Hero动画

内容的提问来源于stack exchange,提问作者Abhishek Upmanyu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:39:41