356 lines
9.4 KiB
Dart
356 lines
9.4 KiB
Dart
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<PublishScreen> {
|
|
final TextEditingController _titleController = TextEditingController();
|
|
final TextEditingController _contentController = TextEditingController();
|
|
final TextEditingController _locationController = TextEditingController();
|
|
final ImagePicker _picker = ImagePicker();
|
|
|
|
List<XFile> _images = [];
|
|
XFile? _video;
|
|
bool _isVideo = false;
|
|
|
|
Future<void> _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<XFile> selectedImages = await _picker.pickMultiImage();
|
|
|
|
if (selectedImages.isNotEmpty) {
|
|
setState(() {
|
|
int availableSlots = 9 - _images.length;
|
|
_images.addAll(selectedImages.take(availableSlots));
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> _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();
|
|
}
|
|
}
|