149 lines
4.4 KiB
Dart
149 lines
4.4 KiB
Dart
import 'dart:io';
|
||
|
||
import 'package:extended_image/extended_image.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:photo_view/photo_view.dart';
|
||
import 'package:photo_view/photo_view_gallery.dart';
|
||
import 'package:yumi/app/constants/sc_global_config.dart';
|
||
|
||
class ImagePreviewPage extends StatefulWidget {
|
||
final List<String> imageUrls;
|
||
final int initialIndex;
|
||
final PageController? pageController;
|
||
|
||
const ImagePreviewPage({
|
||
Key? key,
|
||
required this.imageUrls,
|
||
this.initialIndex = 0,
|
||
this.pageController,
|
||
}) : super(key: key);
|
||
|
||
@override
|
||
_ImagePreviewPageState createState() => _ImagePreviewPageState();
|
||
}
|
||
|
||
class _ImagePreviewPageState extends State<ImagePreviewPage> {
|
||
late PageController _pageController;
|
||
late int _currentIndex;
|
||
bool _showAppBar = true;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
|
||
_currentIndex = widget.initialIndex;
|
||
_pageController =
|
||
widget.pageController ??
|
||
PageController(initialPage: widget.initialIndex);
|
||
}
|
||
|
||
void _onPageChanged(int index) {
|
||
setState(() {
|
||
_currentIndex = index;
|
||
});
|
||
}
|
||
|
||
void _toggleAppBar() {
|
||
setState(() {
|
||
_showAppBar = !_showAppBar;
|
||
});
|
||
}
|
||
|
||
void _onTap() {
|
||
_toggleAppBar();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
backgroundColor: SCGlobalConfig.businessLogicStrategy.getImagePreviewBackgroundColor(),
|
||
body: Stack(
|
||
children: [
|
||
// 图片画廊
|
||
PhotoViewGallery.builder(
|
||
scrollPhysics: const BouncingScrollPhysics(),
|
||
builder: _buildImage,
|
||
itemCount: widget.imageUrls.length,
|
||
loadingBuilder:
|
||
(context, event) => Center(
|
||
child: Container(
|
||
width: 20.0,
|
||
height: 20.0,
|
||
child: CircularProgressIndicator(
|
||
value:
|
||
event == null
|
||
? 0
|
||
: event.cumulativeBytesLoaded /
|
||
event.expectedTotalBytes!,
|
||
color: SCGlobalConfig.businessLogicStrategy.getImagePreviewLoadingIndicatorColor(),
|
||
),
|
||
),
|
||
),
|
||
backgroundDecoration: BoxDecoration(color: SCGlobalConfig.businessLogicStrategy.getImagePreviewGalleryBackgroundColor()),
|
||
pageController: _pageController,
|
||
onPageChanged: _onPageChanged,
|
||
enableRotation: true,
|
||
customSize: MediaQuery.of(context).size,
|
||
),
|
||
|
||
// 顶部应用栏
|
||
if (_showAppBar) _buildAppBar(),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
PhotoViewGalleryPageOptions _buildImage(BuildContext context, int index) {
|
||
final imageUrl = widget.imageUrls[index];
|
||
return PhotoViewGalleryPageOptions(
|
||
imageProvider: _getImageProvider(imageUrl),
|
||
initialScale: PhotoViewComputedScale.contained,
|
||
minScale: PhotoViewComputedScale.contained * 0.8,
|
||
maxScale: PhotoViewComputedScale.covered * 2.0,
|
||
heroAttributes: PhotoViewHeroAttributes(tag: imageUrl),
|
||
onTapUp: (_, __, ___) => _onTap(),
|
||
);
|
||
}
|
||
|
||
ImageProvider _getImageProvider(String imageUrl) {
|
||
if (imageUrl.startsWith('http')) {
|
||
return ExtendedNetworkImageProvider(
|
||
imageUrl,
|
||
cache: true, // 启用缓存(默认即为true)
|
||
cacheMaxAge: Duration(days: 7), // 设置缓存有效期
|
||
);
|
||
} else {
|
||
return FileImage(File(imageUrl));
|
||
}
|
||
}
|
||
|
||
Widget _buildAppBar() {
|
||
return Positioned(
|
||
top: 0,
|
||
left: 0,
|
||
right: 0,
|
||
child: AppBar(
|
||
backgroundColor: SCGlobalConfig.businessLogicStrategy.getImagePreviewAppBarBackgroundColor(),
|
||
elevation: 0,
|
||
leading: IconButton(
|
||
icon: Icon(Icons.arrow_back, color: SCGlobalConfig.businessLogicStrategy.getImagePreviewBackIconColor()),
|
||
onPressed: () => Navigator.of(context).pop(),
|
||
),
|
||
title: Text(
|
||
'${_currentIndex + 1} / ${widget.imageUrls.length}',
|
||
style: TextStyle(color: SCGlobalConfig.businessLogicStrategy.getImagePreviewTextColor()),
|
||
),
|
||
centerTitle: true,
|
||
),
|
||
);
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
if (widget.pageController == null) {
|
||
_pageController.dispose();
|
||
}
|
||
super.dispose();
|
||
}
|
||
}
|