feat:更新美食记录表单
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:food_hub_app/config/app_config.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
@@ -91,138 +89,123 @@ class _ImagePreviewPageState extends State<ImagePreviewPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildNetworkImage(
|
||||
BuildContext context,
|
||||
List<String> imageUrls,
|
||||
int index,
|
||||
) {
|
||||
return AspectRatio(
|
||||
aspectRatio: 4 / 3,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
showFullScreenImage(context, imageUrls, index);
|
||||
},
|
||||
child: Image.network(
|
||||
'${AppConfig.imageBaseUrl}${imageUrls[index]}',
|
||||
fit: BoxFit.cover,
|
||||
loadingBuilder: (context, child, loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return buildImageLoadingIndicator(loadingProgress);
|
||||
},
|
||||
errorBuilder: (context, error, stackTrace) => buildErrorImage(),
|
||||
),
|
||||
class CommonImage extends StatelessWidget {
|
||||
final List<String> imageUrls;
|
||||
final int index;
|
||||
|
||||
const CommonImage({super.key, required this.imageUrls, required this.index});
|
||||
|
||||
Widget _buildImageLoadingIndicator(ImageChunkEvent? progress) {
|
||||
final value =
|
||||
progress?.expectedTotalBytes != null
|
||||
? progress!.cumulativeBytesLoaded / progress.expectedTotalBytes!
|
||||
: null;
|
||||
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: CircularProgressIndicator(value: value),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildImagePreviewItem({
|
||||
required BuildContext context,
|
||||
required List<String> imageUrls,
|
||||
required int index,
|
||||
required VoidCallback onRemoveImage,
|
||||
}) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Stack(
|
||||
children: [
|
||||
buildNetworkImage(context, imageUrls, index),
|
||||
buildDeleteImage(onRemoveImage: onRemoveImage),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget _buildErrorImage() {
|
||||
return Container(
|
||||
color: Colors.grey[200],
|
||||
child: const Icon(Icons.image, color: Colors.grey, size: 30),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildImageLoadingIndicator(ImageChunkEvent? loadingProgress) {
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: CircularProgressIndicator(
|
||||
value:
|
||||
loadingProgress?.expectedTotalBytes != null
|
||||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildErrorImage() {
|
||||
return Container(
|
||||
color: Colors.grey[200],
|
||||
child: const Icon(Icons.image, color: Colors.grey, size: 30),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPhotoView(ImageProvider imageProvider) {
|
||||
return PhotoView(
|
||||
imageProvider: imageProvider,
|
||||
backgroundDecoration: const BoxDecoration(color: Colors.transparent),
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
maxScale: PhotoViewComputedScale.covered * 2,
|
||||
initialScale: PhotoViewComputedScale.contained,
|
||||
loadingBuilder: (context, event) => buildImageLoadingIndicator(event),
|
||||
errorBuilder: (context, error, stackTrace) => buildErrorImage(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCloseImage(BuildContext context) {
|
||||
return Positioned(
|
||||
top: MediaQuery.of(context).padding.top + 10,
|
||||
right: 20,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.close, color: Colors.white, size: 30),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void showFullScreenImage(
|
||||
BuildContext context,
|
||||
List<String> imageUrls,
|
||||
int index,
|
||||
) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
void _navigateToImagePreview(
|
||||
BuildContext context,
|
||||
List<String> imageUrls,
|
||||
int index,
|
||||
) {
|
||||
final route = MaterialPageRoute(
|
||||
builder:
|
||||
(context) => ImagePreviewPage(images: imageUrls, initialIndex: index),
|
||||
),
|
||||
);
|
||||
// Navigator.of(context).push(
|
||||
// PageRouteBuilder(
|
||||
// opaque: false,
|
||||
// pageBuilder: (
|
||||
// BuildContext context,
|
||||
// Animation<double> animation,
|
||||
// Animation<double> secondaryAnimation,
|
||||
// ) {
|
||||
// return Scaffold(
|
||||
// backgroundColor: Colors.black.withAlpha(200),
|
||||
// body: Stack(
|
||||
// children: [
|
||||
// // 可缩放图片
|
||||
// Positioned.fill(child: _buildPhotoView(imageProvider)),
|
||||
// // 关闭按钮
|
||||
// _buildCloseImage(context),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
);
|
||||
|
||||
Navigator.push(context, route);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AspectRatio(
|
||||
aspectRatio: 4 / 3,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_navigateToImagePreview(context, imageUrls, index);
|
||||
},
|
||||
child: Image.network(
|
||||
'${AppConfig.imageBaseUrl}${imageUrls[index]}',
|
||||
fit: BoxFit.cover,
|
||||
loadingBuilder: (context, child, loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return _buildImageLoadingIndicator(loadingProgress);
|
||||
},
|
||||
errorBuilder: (context, error, stackTrace) => _buildErrorImage(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildImageUploadButton({required VoidCallback onPickImage}) {
|
||||
class ImagePreview extends StatelessWidget {
|
||||
final List<String> imageUrls;
|
||||
final int index;
|
||||
final VoidCallback onRemoveImage;
|
||||
|
||||
const ImagePreview({
|
||||
super.key,
|
||||
required this.imageUrls,
|
||||
required this.index,
|
||||
required this.onRemoveImage,
|
||||
});
|
||||
|
||||
Widget _buildDeleteImage() {
|
||||
return Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: onRemoveImage,
|
||||
child: Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.red,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(Icons.close, color: Colors.white, size: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Stack(
|
||||
children: [
|
||||
CommonImage(imageUrls: imageUrls, index: index),
|
||||
_buildDeleteImage(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildImageUploadButton({required VoidCallback onTap}) {
|
||||
return InkWell(
|
||||
onTap: onPickImage,
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Container(
|
||||
width: 96,
|
||||
@@ -243,22 +226,3 @@ Widget buildImageUploadButton({required VoidCallback onPickImage}) {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDeleteImage({required VoidCallback onRemoveImage}) {
|
||||
return Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: onRemoveImage,
|
||||
child: Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.red,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(Icons.close, color: Colors.white, size: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user