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 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 { 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(); } }