QinGang_interested/lib/customWidget/single_images_viewer.dart

148 lines
4.3 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 SingleImagesViewer extends StatefulWidget {
final String imageUrl;
/// 可选多张图片列表。如果需要列表的话imageUrl可以传空
final List<String>? imageUrls;
/// 可选:初始显示页(默认 0
final int initialIndex;
const SingleImagesViewer({
Key? key,
required this.imageUrl,
this.imageUrls,
this.initialIndex = 0,
}) : super(key: key);
@override
State<SingleImagesViewer> createState() => _SingleImagesViewerState();
}
class _SingleImagesViewerState extends State<SingleImagesViewer> {
late final List<String> _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),
),
),
),
],
),
);
}
}