效果图
实现方式
pubspec.yaml文件中dependencies:下引入photo_view
dependencies:
flutter:
sdk: flutter
photo_view: ^0.14.0
主页代码:
import 'package:flutter/material.dart';
import 'package:flutter_demo/res/listData.dart';
import 'package:flutter_demo/routers/routers.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
//隐藏DEBUG图标
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue),
home: const Scaffold(
body: PhotoViewPage(),
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
class PhotoViewPage extends StatefulWidget {
const PhotoViewPage({super.key});
@override
State createState() => _PhotoViewPageState();
}
class _PhotoViewPageState extends State {
List _list() {
var list = listData.map((value) {
return GestureDetector(
onTap: () {
//item点击路由跳转传参
Navigator.pushNamed(
context,
"/hero",
arguments: {
"imageUrl": value['imageUrl'],
"initialPage": value['id'],
"listData": listData,
},
);
},
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black26),
),
child: Column(
children: [
Hero(
tag: value["imageUrl"],
child: Image.network(value["imageUrl"]),
),
const SizedBox(height: 10),
Text(
value["title"],
style: const TextStyle(fontSize: 18),
),
],
),
),
);
});
return list.toList();
}
@override
Widget build(BuildContext context) {
return SafeArea(
//GridView网格布局
child: GridView.count(
//一行widget数量
crossAxisCount: 2,
//水平子Widget之间间距
crossAxisSpacing: 10,
//垂直子Widget之间间距
mainAxisSpacing: 10,
//外边距
padding: const EdgeInsets.all(10),
//数据
children: _list(),
),
);
}
}
路由跳转需要加入initialRoute和引入自定义路由配置onGenerateRoute。数据用了自定义listData数据。预览图片跳转到自定义图片预览HeroPage页面。图片显示列表用的是GridView网格布局组件。
路由配置routers.dart代码:
import 'package:flutter/material.dart';
import 'package:flutter_demo/form.dart';
import 'package:flutter_demo/hero.dart';
import 'package:flutter_demo/register2.dart';
import 'package:flutter_demo/search.dart';
//配置路由
Map routes = {
"/search": (context) => const SearchPage(),
"/register2": (context) => const Register2(),
"/form": (context, {arguments}) => FormPage(arguments: arguments),
"/hero": (context, {arguments}) => HeroPage(arguments: arguments),
};
//配置onGenerateRoute固定写法,这个方法相当于一个中间件,可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments),
);
return route;
} else {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(context),
);
return route;
}
}
return null;
};
配置中添加跳转页面HeroPage的配置即可。
自定义数据listData.dart代码:
List listData = [
{
"id": 1,
"title": "图一",
"author": "程序员",
"imageUrl": "https://www.itying.com/images/flutter/1.png",
},
{
"id": 2,
"title": "图二",
"author": "程序员",
"imageUrl": "https://www.itying.com/images/flutter/2.png",
},
{
"id": 3,
"title": "图三",
"author": "程序员",
"imageUrl": "https://www.itying.com/images/flutter/3.png",
},
{
"id": 4,
"title": "图四",
"author": "程序员",
"imageUrl": "https://www.itying.com/images/flutter/4.png",
},
{
"id": 5,
"title": "图五",
"author": "程序员",
"imageUrl": "https://www.itying.com/images/flutter/5.png",
},
{
"id": 6,
"title": "图六",
"author": "程序员",
"imageUrl": "https://www.itying.com/images/flutter/6.png",
},
];
点击item跳转并传参:
Navigator.pushNamed(
context,
"/hero",
arguments: {
"imageUrl": value['imageUrl'],
"initialPage": value['id'],
"listData": listData,
},
);
自定义图片预览hero.dart页面:
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view_gallery.dart';
///自定义图片预览页面
class HeroPage extends StatefulWidget {
final Map arguments;
const HeroPage({super.key, required this.arguments});
@override
State createState() => _HeroPageState();
}
class _HeroPageState extends State {
List listData = [];
late int currentPage;
late int initialPage = 0;
@override
void initState() {
super.initState();
listData = widget.arguments["listData"];
initialPage = widget.arguments["initialPage"] - 1;
currentPage = widget.arguments["initialPage"];
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
//点击屏幕关闭本页
Navigator.pop(context);
},
child: Hero(
tag: widget.arguments["imageUrl"],
child: Stack(
children: [
Scaffold(
backgroundColor: Colors.black,
body: Center(
//多图片预览
child: PhotoViewGallery.builder(
itemCount: listData.length,
pageController: PageController(initialPage: initialPage),
onPageChanged: (index) {
setState(() {
currentPage = index + 1;
});
},
builder: (context, index) {
return PhotoViewGalleryPageOptions(
imageProvider: NetworkImage(listData[index]["imageUrl"]),
);
},
),
),
),
//图片张数指示器
Positioned(
left: 0,
right: 0,
bottom: 20,
child: Container(
alignment: Alignment.center,
child: Text(
"$currentPage/${listData.length}",
style: const TextStyle(
color: Colors.white,
fontSize: 16,
decoration: TextDecoration.none,
),
),
),
)
],
),
),
);
}
}
单击页面关闭图片预览用Navigator.pop。多图预览用PhotoViewGallery。单图预览用PhotoView。
photo_view三方库介绍及使用
库特色:单图预览,多图预览,双击放大缩小,双指放大缩小。