79 lines
2.5 KiB
Dart
79 lines
2.5 KiB
Dart
import 'dart:io';
|
||
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:photo_view/photo_view.dart';
|
||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||
|
||
// 查看大图
|
||
class SingleImageViewer extends StatelessWidget {
|
||
final String imageUrl;
|
||
const SingleImageViewer({Key? key, required this.imageUrl}) : super(key: key);
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
ImageProvider provider;
|
||
|
||
// 选择图片来源:网络 / asset / 本地文件(优先检测 http,然后 asset,再文件)
|
||
if (imageUrl.toLowerCase().startsWith('http')) {
|
||
provider = NetworkImage(imageUrl);
|
||
} else if (imageUrl.startsWith('assets/') ||
|
||
imageUrl.startsWith('package:') ||
|
||
imageUrl.startsWith('packages/')) {
|
||
// 明确标记为工程资源(asset)
|
||
provider = AssetImage(imageUrl) as ImageProvider;
|
||
} else {
|
||
// 不是明确的网络或 asset 路径 —— 在非 web 平台尝试作为文件路径
|
||
if (!kIsWeb) {
|
||
try {
|
||
final file = File(imageUrl);
|
||
if (file.existsSync()) {
|
||
provider = FileImage(file);
|
||
} else {
|
||
// 文件不存在时尝试作为 asset 路径回退
|
||
provider = AssetImage(imageUrl) as ImageProvider;
|
||
}
|
||
} catch (e) {
|
||
// 任何异常都回退为 asset 尝试(避免抛出)
|
||
provider = AssetImage(imageUrl) as ImageProvider;
|
||
}
|
||
} else {
|
||
// web 平台没有 File API,可直接尝试当作 asset
|
||
provider = AssetImage(imageUrl) as ImageProvider;
|
||
}
|
||
}
|
||
|
||
return Scaffold(
|
||
backgroundColor: Colors.black.withValues(alpha: 0.5),
|
||
appBar: MyAppbar(
|
||
isBack: false,
|
||
actions: [
|
||
IconButton(
|
||
onPressed: () {
|
||
Navigator.of(context).pop();
|
||
},
|
||
icon: const Icon(
|
||
Icons.close,
|
||
color: Colors.white,
|
||
size: 40,
|
||
),
|
||
)
|
||
],
|
||
backgroundColor: Colors.black.withValues(alpha: 0.5),
|
||
title: '',
|
||
),
|
||
body: Center(
|
||
child: PhotoView(
|
||
imageProvider: provider,
|
||
backgroundDecoration: BoxDecoration(color: Colors.black.withValues(alpha: 0.5)),
|
||
minScale: PhotoViewComputedScale.contained,
|
||
maxScale: PhotoViewComputedScale.covered * 2,
|
||
onTapUp: (context, details, controllerValue) {
|
||
Navigator.of(context).pop();
|
||
},
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|