Files
jinzhi/lib/features/assets/presentation/asset_image_preview_page.dart
T
2026-06-23 10:07:35 +08:00

96 lines
2.8 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart' hide AssetImage;
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
import '../data/asset_models.dart';
class AssetImagePreviewPage extends StatefulWidget {
const AssetImagePreviewPage({
super.key,
required this.images,
required this.initialIndex,
});
final List<AssetImage> images;
final int initialIndex;
@override
State<AssetImagePreviewPage> createState() => _AssetImagePreviewPageState();
}
class _AssetImagePreviewPageState extends State<AssetImagePreviewPage> {
late final PageController _pageController;
late int _currentIndex;
@override
void initState() {
super.initState();
_currentIndex = widget.initialIndex.clamp(0, widget.images.length - 1);
_pageController = PageController(initialPage: _currentIndex);
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: Stack(
children: [
PhotoViewGallery.builder(
pageController: _pageController,
itemCount: widget.images.length,
builder: (context, index) {
final image = widget.images[index];
return PhotoViewGalleryPageOptions(
imageProvider: FileImage(File(image.localPath)),
minScale: PhotoViewComputedScale.contained,
maxScale: PhotoViewComputedScale.covered * 2.2,
);
},
onPageChanged: (index) => setState(() {
_currentIndex = index;
}),
backgroundDecoration: const BoxDecoration(color: Colors.black),
),
Positioned(
top: 16,
left: 16,
child: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(Icons.close, color: Colors.white),
),
),
Positioned(
bottom: 24,
left: 0,
right: 0,
child: Center(
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.circular(999),
),
child: Text(
'${_currentIndex + 1}/${widget.images.length}',
style: const TextStyle(color: Colors.white, fontSize: 14),
),
),
),
),
],
),
),
);
}
}