Flutter Hero 动画_Flutter Hero +photo_view 实现微信朋友圈图片预览

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

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

一、Flutter Hero 动画

1、 Hero 动画的使用

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

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)),
          )
        ],
      ),
    );
  }
}


2、配置 Hero 动画的执行时间

1、引入scheduler.dart

import 'package:flutter/scheduler.dart';

2、设置动画时间

  void initState() {
    super.initState();
    timeDilation=5.0;
  }

二、 Hero +photo_view 实现微信朋友圈图片预览

photo_view插件支持预览图片,可放大、缩小、滑动图片

photo_view 官方地址https://pub.dev/packages/photo_view

2.1、photo_view预览单张图片

1、配置依赖

dependencies:
  photo_view: ^0.14.0

2、引入

import 'package:photo_view/photo_view.dart';

3、单张图片的预览

@override
Widget build(BuildContext context) {
  return Container(
    child: PhotoView(
      imageProvider: AssetImage("assets/large-image.jpg"),
    )
  );
}

2.2、photo_view多张图片预览

1、配置依赖

dependencies:
  photo_view: ^0.14.0

2、引入

import 'package:photo_view/photo_view_gallery.dart';

3、多张图片的预览

PhotoViewGallery.builder(
          itemCount: 5,
          builder: ((context, index) {
            return PhotoViewGalleryPageOptions(
                imageProvider: NetworkImage(listData[index]["imageUrl"]));
 }))
 PhotoViewGallery.builder(
                  scrollPhysics: const BouncingScrollPhysics(),
                  builder: (BuildContext context, int index) {
                    return PhotoViewGalleryPageOptions(
                      imageProvider:
                          NetworkImage(widget.imageItems[index]["imageUrl"]),
                    );
                  },
                  scrollDirection: widget.direction,
                  itemCount: widget.imageItems.length,
                  backgroundDecoration:
                      const BoxDecoration(color: Colors.black),
                  pageController: PageController(initialPage: 1),
                  onPageChanged: (index) => setState(() {
                        currentIndex = index;
                  }))

PhotoViewGallery.builder属性:

属性 描述
scrollPhysics BouncingScrollPhysics() 滑动到边界的时候有弹跳的效果
scrollDirection Axis.horizontal 水平 、Axis.vertical垂直方向
backgroundDecoration 背景颜色
builder builder函数 根据配置的itemCount渲染函数
itemCount 数量
pageController PageController(initialPage: 1)
onPageChanged onPageChanged触发的方法

更多详情参考教程以及教程源码

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

回到顶部