import 'dart:io'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; /// 横向一行最多四张图片的添加组件,支持拍照和全屏相册多选 /// 使用示例: /// PhotoPickerRow( /// maxCount: 4, /// onChanged: (List images) { /// // images 列表更新 /// }, /// ), class PhotoPickerRow extends StatefulWidget { final int maxCount; final ValueChanged> onChanged; const PhotoPickerRow({ Key? key, this.maxCount = 4, required this.onChanged, }) : super(key: key); @override _PhotoPickerRowState createState() => _PhotoPickerRowState(); } class _PhotoPickerRowState extends State { final ImagePicker _picker = ImagePicker(); final List _images = []; Future _showPickerOptions() async { showModalBottomSheet( context: context, builder: (_) => SafeArea( child: Wrap( children: [ ListTile( leading: const Icon(Icons.camera_alt), title: const Text('拍照'), onTap: () { Navigator.of(context).pop(); _pickCamera(); }, ), ListTile( leading: const Icon(Icons.photo_library), title: const Text('从相册选择'), onTap: () { Navigator.of(context).pop(); _pickGallery(); }, ), ListTile( leading: const Icon(Icons.close), title: const Text('取消'), onTap: () => Navigator.of(context).pop(), ), ], ), ), ); } Future _pickCamera() async { if (_images.length >= widget.maxCount) return; final XFile? picked = await _picker.pickImage(source: ImageSource.camera); if (picked != null) { setState(() { _images.add(File(picked.path)); }); widget.onChanged(_images); } } Future _pickGallery() async { if (_images.length >= widget.maxCount) return; final remaining = widget.maxCount - _images.length; final List? assets = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( requestType: RequestType.image, maxAssets: remaining, gridCount: 4, ), ); if (assets != null && assets.isNotEmpty) { for (final asset in assets) { if (_images.length >= widget.maxCount) break; final file = await asset.file; if (file != null) { _images.add(file); } } setState(() {}); widget.onChanged(_images); } } void _removeImage(int index) { setState(() { _images.removeAt(index); }); widget.onChanged(_images); } @override Widget build(BuildContext context) { return SizedBox( height: 80, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: _images.length < widget.maxCount ? _images.length + 1 : widget.maxCount, separatorBuilder: (_, __) => const SizedBox(width: 8), itemBuilder: (context, index) { if (index < _images.length) { // 已选图片 return Stack( children: [ ClipRRect( borderRadius: BorderRadius.circular(5), child: Image.file( _images[index], width: 80, height: 80, fit: BoxFit.cover, ), ), Positioned( top: -6, right: -6, child: IconButton( icon: const Icon(Icons.cancel, size: 20, color: Colors.red), onPressed: () => _removeImage(index), ), ), ], ); } else { // 添加按钮 return GestureDetector( onTap: _showPickerOptions, child: Container( width: 80, height: 80, decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(5), ), child: const Center( child: Icon(Icons.camera_alt, color: Colors.grey), ), ), ); } }, ), ); } }