import 'dart:io'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/pages/message/image_viewer_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:im_flutter_sdk/im_flutter_sdk.dart'; class ImageItem extends StatelessWidget { final EMImageMessageBody imageBody; final bool isSentByMe; final bool showTime; final String formattedTime; final EMMessage message; // 添加消息对象以获取状态 final VoidCallback? onResend; // 添加重发回调 const ImageItem({ required this.imageBody, required this.isSentByMe, required this.showTime, required this.formattedTime, required this.message, this.onResend, super.key, }); @override Widget build(BuildContext context) { return Column( children: [ // 显示时间 if (showTime) _buildTimeLabel(), Container( padding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 8.h, ), child: Builder( builder: (context) { // 计算图片尺寸 double maxWidth = 180.w; double width = maxWidth; double height = width * (304 / 289); // 按289:304比例计算高度 final imageHeight = height + 10.h; // 加上 margin top (10.h) return Row( mainAxisAlignment: isSentByMe ? MainAxisAlignment.end : MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ if (!isSentByMe) _buildAvatar(), if (!isSentByMe) SizedBox(width: 8.w), // 发送消息时,状态在左侧,与图片垂直居中对齐 if (isSentByMe) SizedBox( height: imageHeight, child: Center( child: _buildMessageStatus(), ), ), if (isSentByMe) SizedBox(width: 10.w), GestureDetector( onTap: _onImageTap, child: Container( margin: EdgeInsets.only(top: 10.h), decoration: BoxDecoration( color: isSentByMe ? Color(0xff8E7BF6) : Colors.white, borderRadius: BorderRadius.circular(18.w), ), child: ClipRRect( borderRadius: BorderRadius.circular(18.w), child: _buildImage(), ), ), ), if (isSentByMe) SizedBox(width: 8.w), if (isSentByMe) _buildAvatar(), ], ); }, ), ), ], ); } // 构建时间标签 Widget _buildTimeLabel() { return Container( alignment: Alignment.center, padding: EdgeInsets.symmetric( horizontal: 16.w, ), child: Container( padding: EdgeInsets.symmetric( horizontal: 12.w, ), child: Text( formattedTime, style: TextStyle( fontSize: 12.sp, color: Colors.grey, ), ), ), ); } // 构建头像 Widget _buildAvatar() { return Container( width: 40.w, height: 40.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.w), image: DecorationImage( image: AssetImage(Assets.imagesAvatarsExample), fit: BoxFit.cover, ), ), ); } // 构建图片 Widget _buildImage() { // 按289x304比例计算图片尺寸 // 限制最大宽度为289,高度按比例计算 double maxWidth = 180.w; double width = maxWidth; double height = width * (304 / 289); // 按289:304比例计算高度 // 尝试显示本地图片 final localPath = imageBody.localPath; if (localPath.isNotEmpty) { return Image.file( File(localPath), width: width, height: height, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return _buildErrorContainer(width, height); }, ); } // 尝试显示网络原图 final remotePath = imageBody.remotePath; if (remotePath != null && remotePath.isNotEmpty) { return Image.network( remotePath, width: width, height: height, fit: BoxFit.cover, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) return child; return _buildLoadingContainer(width, height); }, errorBuilder: (context, error, stackTrace) { return _buildErrorContainer(width, height); }, ); } // 默认显示错误容器 return _buildErrorContainer(width, height); } // 构建加载中的容器(网络图片加载时) Widget _buildLoadingContainer(double width, double height) { return Container( width: width, height: height, decoration: BoxDecoration( borderRadius: BorderRadius.circular(18.w), color: Colors.grey[200], ), child: Center( child: CircularProgressIndicator( strokeWidth: 2.w, valueColor: AlwaysStoppedAnimation( Colors.grey[400]!, ), ), ), ); } // 构建消息状态(发送中、已发送、失败重发) Widget _buildMessageStatus() { // 只对发送的消息显示状态 if (!isSentByMe) { return SizedBox.shrink(); } // 检查消息状态 final status = message.status; if (status == MessageStatus.FAIL) { // 发送失败,显示重发按钮 return GestureDetector( onTap: onResend, child: Container( width: 20.w, height: 20.w, decoration: BoxDecoration( color: Colors.red.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.refresh, size: 14.w, color: Colors.red, ), ), ); } else if (status == MessageStatus.PROGRESS) { // 发送中,显示加载动画 return Container( width: 16.w, height: 16.w, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( Colors.grey, ), ), ); } else { // 发送成功,不显示任何状态 return SizedBox.shrink(); } } // 构建错误容器 Widget _buildErrorContainer(double width, double height) { return Container( width: width, height: height, padding: EdgeInsets.all(8.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(18.w), color: Colors.grey[200], ), alignment: Alignment.center, child: Icon( Icons.image_not_supported, size: 32.w, color: Colors.grey[400], ), ); } // 点击图片事件 void _onImageTap() { // 优先使用本地路径,如果没有则使用网络路径 String? imagePath = imageBody.localPath; String? imageUrl = imageBody.remotePath; // 打开图片查看器 Get.to( () => ImageViewerPage( imagePath: imagePath, imageUrl: imageUrl, ), transition: Transition.fade, duration: const Duration(milliseconds: 300), ); } }