import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; class SingleImageViewer extends StatefulWidget { final String imageUrl; /// 可选:多张图片列表。如果需要列表的话,imageUrl可以传空 final List? imageUrls; /// 可选:初始显示页(默认 0) final int initialIndex; const SingleImageViewer({ Key? key, required this.imageUrl, this.imageUrls, this.initialIndex = 0, }) : super(key: key); @override State createState() => _SingleImageViewerState(); } class _SingleImageViewerState extends State { late final List _urls; late final PageController _pageController; int _currentIndex = 0; @override void initState() { super.initState(); // 优先使用 imageUrls if (widget.imageUrls != null && widget.imageUrls!.isNotEmpty) { _urls = widget.imageUrls!; } else { _urls = [widget.imageUrl]; } _currentIndex = (widget.initialIndex >= 0 && widget.initialIndex < _urls.length) ? widget.initialIndex : 0; _pageController = PageController(initialPage: _currentIndex); } ImageProvider _providerFromUrl(String imageUrl) { final lower = imageUrl.toLowerCase(); if (lower.startsWith('http')) { return NetworkImage(imageUrl); } else if (imageUrl.startsWith('assets/') || imageUrl.startsWith('package:') || imageUrl.startsWith('packages/')) { return AssetImage(imageUrl); } else { if (!kIsWeb) { try { final file = File(imageUrl); if (file.existsSync()) { return FileImage(file); } else { return AssetImage(imageUrl); } } catch (e) { return AssetImage(imageUrl); } } else { return AssetImage(imageUrl); } } } @override void dispose() { _pageController.dispose(); super.dispose(); } Color _bgColor() => Colors.black.withOpacity(0.9); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: _bgColor(), appBar: MyAppbar( isBack: false, actions: [ IconButton( onPressed: () => Navigator.of(context).pop(), icon: const Icon( Icons.close, color: Colors.white, size: 40, ), ), ], backgroundColor: _bgColor(), title: '', ), body: Stack( children: [ PhotoViewGallery.builder( pageController: _pageController, itemCount: _urls.length, onPageChanged: (index) => setState(() => _currentIndex = index), builder: (context, index) { final url = _urls[index]; return PhotoViewGalleryPageOptions( imageProvider: _providerFromUrl(url), minScale: PhotoViewComputedScale.contained, maxScale: PhotoViewComputedScale.covered * 2, onTapUp: (context, details, controllerValue) { Navigator.of(context).pop(); }, ); }, backgroundDecoration: BoxDecoration(color: _bgColor()), // enableRotation: false, // 如果需要可打开旋转 loadingBuilder: (context, progress) => const Center( child: CircularProgressIndicator(), ), ), // 页码指示 if (_urls.length > 1) Positioned( right: 12, top: 12 + MediaQuery.of(context).padding.top, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.black.withOpacity(0.45), borderRadius: BorderRadius.circular(16), ), child: Text( '${_currentIndex + 1} / ${_urls.length}', style: const TextStyle(color: Colors.white, fontSize: 14), ), ), ), ], ), ); } }