import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; class PublishScreen extends StatefulWidget { @override _PublishScreenState createState() => _PublishScreenState(); } class _PublishScreenState extends State { final TextEditingController _titleController = TextEditingController(); final TextEditingController _contentController = TextEditingController(); final TextEditingController _locationController = TextEditingController(); final ImagePicker _picker = ImagePicker(); List _images = []; XFile? _video; bool _isVideo = false; Future _pickImages() async { if (_isVideo) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('已选择视频,不能再选择图片')), ); return; } if (_images.length >= 9) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('最多只能选择9张图片')), ); return; } final List selectedImages = await _picker.pickMultiImage(); if (selectedImages.isNotEmpty) { setState(() { int availableSlots = 9 - _images.length; _images.addAll(selectedImages.take(availableSlots)); }); } } Future _pickVideo() async { if (_images.isNotEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('已选择图片,不能再选择视频')), ); return; } final XFile? video = await _picker.pickVideo(source: ImageSource.gallery); if (video != null) { setState(() { _video = video; _isVideo = true; }); } } void _removeImage(int index) { setState(() { _images.removeAt(index); }); } void _removeVideo() { setState(() { _video = null; _isVideo = false; }); } void _publish() { if (_titleController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('请输入标题')), ); return; } if (_images.isEmpty && _video == null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('请至少添加一张图片或一个视频')), ); return; } // TODO: 实际发布逻辑 ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('发布成功!'), backgroundColor: Color(0xFFFF6B35), ), ); Navigator.pop(context); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFFFF8F0), appBar: AppBar( title: Text('发布活动'), actions: [ TextButton( onPressed: _publish, child: Text( '发布', style: TextStyle( color: Color(0xFFFF6B35), fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ], ), body: SingleChildScrollView( child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题输入 TextField( controller: _titleController, decoration: InputDecoration( hintText: '输入活动标题...', border: InputBorder.none, hintStyle: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.grey[400], ), ), style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), maxLines: 1, ), Divider(), SizedBox(height: 16), // 内容输入 TextField( controller: _contentController, decoration: InputDecoration( hintText: '分享活动详情...', border: InputBorder.none, hintStyle: TextStyle(color: Colors.grey[400]), ), maxLines: 5, ), SizedBox(height: 20), // 图片/视频网格 _buildMediaGrid(), SizedBox(height: 20), // 位置输入 Row( children: [ Icon(Icons.location_on, color: Color(0xFFFF6B35)), SizedBox(width: 8), Expanded( child: TextField( controller: _locationController, decoration: InputDecoration( hintText: '添加位置', border: InputBorder.none, hintStyle: TextStyle(color: Colors.grey[400]), ), ), ), ], ), Divider(), ], ), ), ), ); } Widget _buildMediaGrid() { return Wrap( spacing: 8, runSpacing: 8, children: [ // 显示已选择的图片 if (!_isVideo) ..._images.asMap().entries.map((entry) { int index = entry.key; XFile image = entry.value; return _buildImageItem(image, index); }).toList(), // 显示已选择的视频 if (_isVideo && _video != null) _buildVideoItem(_video!), // 添加按钮 if ((_images.length < 9 && !_isVideo) || (_images.isEmpty && !_isVideo)) _buildAddButton(), ], ); } Widget _buildImageItem(XFile image, int index) { return Stack( children: [ Container( width: 100, height: 100, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), image: DecorationImage( image: FileImage(File(image.path)), fit: BoxFit.cover, ), ), ), Positioned( top: 4, right: 4, child: GestureDetector( onTap: () => _removeImage(index), child: Container( width: 24, height: 24, decoration: BoxDecoration( color: Colors.black.withOpacity(0.5), shape: BoxShape.circle, ), child: Icon( Icons.close, color: Colors.white, size: 16, ), ), ), ), ], ); } Widget _buildVideoItem(XFile video) { return Stack( children: [ Container( width: 100, height: 100, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.black, ), child: Center( child: Icon( Icons.play_circle_outline, color: Colors.white, size: 40, ), ), ), Positioned( top: 4, right: 4, child: GestureDetector( onTap: _removeVideo, child: Container( width: 24, height: 24, decoration: BoxDecoration( color: Colors.black.withOpacity(0.5), shape: BoxShape.circle, ), child: Icon( Icons.close, color: Colors.white, size: 16, ), ), ), ), ], ); } Widget _buildAddButton() { return GestureDetector( onTap: () { showModalBottomSheet( context: context, builder: (context) { return SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: Icon(Icons.image, color: Color(0xFFFF6B35)), title: Text('选择图片'), onTap: () { Navigator.pop(context); _pickImages(); }, ), ListTile( leading: Icon(Icons.videocam, color: Color(0xFFFF6B35)), title: Text('选择视频'), onTap: () { Navigator.pop(context); _pickVideo(); }, ), ], ), ); }, ); }, child: Container( width: 100, height: 100, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.grey[300]!), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.add, size: 32, color: Colors.grey[400]), SizedBox(height: 4), Text( '添加', style: TextStyle(fontSize: 12, color: Colors.grey[400]), ), ], ), ), ); } @override void dispose() { _titleController.dispose(); _contentController.dispose(); _locationController.dispose(); super.dispose(); } }