Flutter Hero 动画_Flutter Hero +photo_view 实现微信朋友圈图片预览
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