Flutter Hero 动画

发布于 1 年前 作者 phonegap100 312 次浏览 最后一次编辑是 1 年前 来自 分享

Flutter Hero 动画对应视频教程https://www.bilibili.com/video/BV1S4411E7LY?p=48

微信朋友圈点击小图片的时候会有一个动画效果到大图预览,这个动画效果就可以使用Hero 动画实现。

Flutter Hero 动画 指的是可以在路由(页面)之间“飞行”的 widget,简单来说 Hero 动画就是在路由切换时,有一个共享的widget 可以在新旧路由间切换。

home.dart

import 'package:flutter/material.dart';
import '../../res/listData.dart';

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Widget> _getListData() {
    var tempList = listData.map((value) {
      return GestureDetector(
        onTap: () {
          Navigator.pushNamed(context, "/hero",
              arguments: {
                "imageUrl": value['imageUrl'],
                "description":value['description'],
              });
        },
        child: Container(
            decoration: BoxDecoration(
                border: Border.all(
                    color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),
            child: Column(
              children: <Widget>[
                Hero(
                    tag: value['imageUrl'],
                    child: Image.network(value['imageUrl'])),
                const SizedBox(height: 12),
                Text(
                  value['title'],
                  textAlign: TextAlign.center,
                  style: const TextStyle(fontSize: 20),
                )
              ],
            )),
      );
    });
    // ('xxx','xxx')
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisSpacing: 10.0, //水平子 Widget 之间间距
      mainAxisSpacing: 10.0, //垂直子 Widget 之间间距
      padding: const EdgeInsets.all(10),
      crossAxisCount: 2, //一行的 Widget 数量
      // childAspectRatio:0.7,  //宽度和高度的比例
      children: _getListData(),
    );
  }
}

hero.dart

import 'package:flutter/material.dart';

class HeroPage extends StatefulWidget {
  final Map arguments;
  const HeroPage({super.key, required this.arguments});

  @override
  State<HeroPage> createState() => _HeroPageState();
}

class _HeroPageState extends State<HeroPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("详情页面"),
      ),
      body: ListView(
        children: [
          Hero(
              tag: widget.arguments["imageUrl"],
              child: Image.network(widget.arguments["imageUrl"])),
          const SizedBox(height: 20),
          Padding(
            padding: const EdgeInsets.all(5),
            child: Text(widget.arguments["description"],
                style: const TextStyle(fontSize: 22)),
          )
        ],
      ),
    );
  }
}


配置Flutter Hero 动画的执行时间

1、引入scheduler.dart

import 'package:flutter/scheduler.dart';

2、设置动画时间

  void initState() {
    super.initState();
    timeDilation=5.0;
  }
回到顶部