You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
5.2 KiB
182 lines
5.2 KiB
import 'dart:io';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:extended_image/extended_image.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
/// 图片查看器页面
|
|
class ImageViewerPage extends StatelessWidget {
|
|
final String? imageUrl;
|
|
final String? imagePath;
|
|
|
|
const ImageViewerPage({
|
|
this.imageUrl,
|
|
this.imagePath,
|
|
super.key,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
body: Stack(
|
|
children: [
|
|
// 图片查看区域
|
|
Center(
|
|
child: _buildImage(),
|
|
),
|
|
// 关闭按钮
|
|
Positioned(
|
|
top: MediaQuery.of(context).padding.top + 10,
|
|
right: 16,
|
|
child: GestureDetector(
|
|
onTap: () => Get.back(),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: Colors.black.withOpacity(0.5),
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: const Icon(
|
|
Icons.close,
|
|
color: Colors.white,
|
|
size: 24,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildImage() {
|
|
// 本地图片
|
|
if (imagePath != null && imagePath!.isNotEmpty) {
|
|
return ExtendedImage.file(
|
|
File(imagePath!),
|
|
fit: BoxFit.contain,
|
|
mode: ExtendedImageMode.gesture,
|
|
initGestureConfigHandler: (state) {
|
|
return GestureConfig(
|
|
minScale: 0.9,
|
|
animationMinScale: 0.7,
|
|
maxScale: 3.0,
|
|
animationMaxScale: 3.5,
|
|
speed: 1.0,
|
|
inertialSpeed: 100.0,
|
|
initialScale: 1.0,
|
|
inPageView: false,
|
|
initialAlignment: InitialAlignment.center,
|
|
);
|
|
},
|
|
loadStateChanged: (state) {
|
|
switch (state.extendedImageLoadState) {
|
|
case LoadState.loading:
|
|
return const Center(
|
|
child: CircularProgressIndicator(
|
|
color: Colors.white,
|
|
),
|
|
);
|
|
case LoadState.completed:
|
|
return null; // 返回 null 显示图片
|
|
case LoadState.failed:
|
|
return const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
Icons.error_outline,
|
|
color: Colors.white,
|
|
size: 48,
|
|
),
|
|
SizedBox(height: 16),
|
|
Text(
|
|
'图片加载失败',
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
// 网络图片
|
|
if (imageUrl != null && imageUrl!.isNotEmpty) {
|
|
return ExtendedImage.network(
|
|
imageUrl!,
|
|
fit: BoxFit.contain,
|
|
mode: ExtendedImageMode.gesture,
|
|
cache: true,
|
|
initGestureConfigHandler: (state) {
|
|
return GestureConfig(
|
|
minScale: 0.9,
|
|
animationMinScale: 0.7,
|
|
maxScale: 3.0,
|
|
animationMaxScale: 3.5,
|
|
speed: 1.0,
|
|
inertialSpeed: 100.0,
|
|
initialScale: 1.0,
|
|
inPageView: false,
|
|
initialAlignment: InitialAlignment.center,
|
|
);
|
|
},
|
|
loadStateChanged: (state) {
|
|
switch (state.extendedImageLoadState) {
|
|
case LoadState.loading:
|
|
return Center(
|
|
child: CircularProgressIndicator(
|
|
color: Colors.white,
|
|
value: state.loadingProgress?.expectedTotalBytes != null
|
|
? state.loadingProgress!.cumulativeBytesLoaded /
|
|
state.loadingProgress!.expectedTotalBytes!
|
|
: null,
|
|
),
|
|
);
|
|
case LoadState.completed:
|
|
return null; // 返回 null 显示图片
|
|
case LoadState.failed:
|
|
return const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
Icons.error_outline,
|
|
color: Colors.white,
|
|
size: 48,
|
|
),
|
|
SizedBox(height: 16),
|
|
Text(
|
|
'图片加载失败',
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
// 没有图片时显示错误
|
|
return const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
Icons.image_not_supported,
|
|
color: Colors.white,
|
|
size: 48,
|
|
),
|
|
SizedBox(height: 16),
|
|
Text(
|
|
'没有可显示的图片',
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|