import 'package:cached_network_image/cached_network_image.dart'; import 'package:chat/configs/app_colors.dart'; import 'package:chat/views/moments/index/widgets/media_preview.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; class GridMedia extends StatelessWidget { final List? mediaList; const GridMedia(this.mediaList, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { if (mediaList?.length == 1) { return ConstrainedBox( constraints: BoxConstraints( maxHeight: Get.width * 0.5, maxWidth: Get.width * 0.5, minHeight: 50, minWidth: 50, ), child: mediaList!.first.split('?').first.isImageFileName ? imageWidget(mediaList![0], 0) : videoWidget(mediaList![0], 0), ); } else if (mediaList?.length == 2 || mediaList?.length == 4) { return GridView.builder( padding: EdgeInsets.zero, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 8, crossAxisSpacing: 8, childAspectRatio: 1, ), itemCount: mediaList?.length, itemBuilder: (context, index) { final source = mediaList![index]; if (source.split('?').first.isImageFileName) { return imageWidget(source, index); } return videoWidget(source, index); }, ); } else { return GridView.builder( padding: EdgeInsets.zero, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 8, crossAxisSpacing: 8, childAspectRatio: 1, ), itemCount: mediaList?.length ?? 0, itemBuilder: (context, index) { final source = mediaList![index]; if (source.split('?').first.isImageFileName) { return imageWidget(source, index); } return videoWidget(source, index); }, ); } } Widget videoWidget(String sourse, int index) { return GestureDetector( onTap: () { pushToPreview(index); }, child: const ColoredBox( color: AppColors.black, child: Center( child: ClipOval( child: ColoredBox( color: AppColors.white, child: SizedBox.square( dimension: 30, child: Icon(Icons.play_arrow), ), ), ), ), ), // ignore: todo // TODO: 缩略图太耗流量 // child: FutureBuilder( // // future: getVideoThumbnail(sourse), // builder: (context, snapshot) { // if (snapshot.data == null) { // return Container(color: Colors.white); // } else { // return DecoratedBox( // decoration: BoxDecoration( // image: DecorationImage( // image: MemoryImage(snapshot.data!), // fit: BoxFit.cover, // ), // ), // child: const Center( // child: Icon( // Icons.play_arrow_rounded, // color: Colors.white, // size: 40, // ), // ), // ); // } // }, // ), ); } Widget imageWidget(String source, int index) { return GestureDetector( onTap: () { pushToPreview(index); }, child: ClipRRect( borderRadius: BorderRadius.circular(4), child: CachedNetworkImage( imageUrl: source, alignment: Alignment.center, fit: BoxFit.cover, ), ), ); } void pushToPreview(int index) { Get.dialog( MomentMediaPreview( mediaSourceList: mediaList!, initialPage: index, ), useSafeArea: false, ); } }