banxiang/lib/screens/activity_detail_screen.dart
2026-02-17 16:10:18 +08:00

488 lines
16 KiB
Dart

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
class ActivityDetailScreen extends StatefulWidget {
final Map<String, dynamic> activity;
ActivityDetailScreen({required this.activity});
@override
_ActivityDetailScreenState createState() => _ActivityDetailScreenState();
}
class _ActivityDetailScreenState extends State<ActivityDetailScreen> {
final TextEditingController _commentController = TextEditingController();
bool _isLiked = false;
int _likeCount = 0;
int _currentImageIndex = 0;
// 模拟评论数据
final List<Map<String, dynamic>> _comments = [
{
'userName': '张阿姨',
'avatar': 'https://i.pravatar.cc/150?img=1',
'content': '这个活动真不错,我也想参加!',
'time': '2小时前',
'likes': 5,
},
{
'userName': '李大爷',
'avatar': 'https://i.pravatar.cc/150?img=2',
'content': '上周参加过,很有意思',
'time': '5小时前',
'likes': 3,
},
{
'userName': '王阿姨',
'avatar': 'https://i.pravatar.cc/150?img=3',
'content': '地点在哪里呀?',
'time': '1天前',
'likes': 2,
},
];
@override
void initState() {
super.initState();
_likeCount = (widget.activity['participants'] as int) * 2;
}
void _toggleLike() {
setState(() {
_isLiked = !_isLiked;
_likeCount += _isLiked ? 1 : -1;
});
}
void _postComment() {
if (_commentController.text.trim().isEmpty) {
return;
}
setState(() {
_comments.insert(0, {
'userName': '',
'avatar': 'https://i.pravatar.cc/150?img=10',
'content': _commentController.text,
'time': '刚刚',
'likes': 0,
});
});
_commentController.clear();
FocusScope.of(context).unfocus();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('评论成功!'),
backgroundColor: Color(0xFFFF6B35),
duration: Duration(seconds: 1),
),
);
}
@override
Widget build(BuildContext context) {
// 模拟多张图片
final images = [
widget.activity['image'],
'https://picsum.photos/seed/${widget.activity['title'].hashCode + 1}/400/300',
'https://picsum.photos/seed/${widget.activity['title'].hashCode + 2}/400/300',
];
return Scaffold(
backgroundColor: const Color(0xFFFFF8F0),
body: CustomScrollView(
slivers: [
// 图片轮播
SliverAppBar(
expandedHeight: 400,
pinned: true,
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.white),
flexibleSpace: FlexibleSpaceBar(
background: Stack(
children: [
CarouselSlider(
options: CarouselOptions(
height: 400,
viewportFraction: 1.0,
onPageChanged: (index, reason) {
setState(() {
_currentImageIndex = index;
});
},
),
items: images.map((imageUrl) {
return Container(
width: double.infinity,
color: Colors.grey[200],
child: Stack(
children: [
Center(
child: Icon(Icons.image, size: 60, color: Colors.grey[400]),
),
Image.network(
imageUrl,
width: double.infinity,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
color: Colors.grey[200],
child: Center(
child: Icon(Icons.image, size: 60, color: Colors.grey[400]),
),
);
},
),
],
),
);
}).toList(),
),
// 指示器
Positioned(
bottom: 20,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: images.asMap().entries.map((entry) {
return Container(
width: 8,
height: 8,
margin: EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _currentImageIndex == entry.key
? Colors.white
: Colors.white.withOpacity(0.4),
),
);
}).toList(),
),
),
],
),
),
),
// 内容区域
SliverToBoxAdapter(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 标题
Text(
widget.activity['title'],
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
SizedBox(height: 12),
// 用户信息
Row(
children: [
CircleAvatar(
radius: 20,
backgroundImage: NetworkImage('https://i.pravatar.cc/150?img=5'),
),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'活动发起人',
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
Text(
'2天前',
style: TextStyle(
fontSize: 12,
color: Color(0xFF999999),
),
),
],
),
),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFFF6B35),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 8),
),
child: Text('关注'),
),
],
),
SizedBox(height: 16),
// 活动详情
Text(
'这是一个非常有趣的活动,欢迎大家一起来参加!活动内容丰富多彩,适合所有年龄段的朋友。我们将在${widget.activity['location']}举行,期待您的到来!',
style: TextStyle(
fontSize: 15,
color: Color(0xFF333333),
height: 1.6,
),
),
SizedBox(height: 16),
// 位置和报名信息
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Color(0xFFFFF5F0),
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Row(
children: [
Icon(Icons.location_on, size: 18, color: Color(0xFFFF6B35)),
SizedBox(width: 8),
Text(
widget.activity['location'],
style: TextStyle(fontSize: 14),
),
],
),
SizedBox(height: 8),
Row(
children: [
Icon(Icons.people, size: 18, color: Color(0xFFFF6B35)),
SizedBox(width: 8),
Text(
'已有 ${widget.activity['participants']} 人报名',
style: TextStyle(fontSize: 14),
),
],
),
],
),
),
],
),
),
Divider(thickness: 8, color: Color(0xFFF5F5F5)),
// 评论区标题
Padding(
padding: EdgeInsets.all(16),
child: Row(
children: [
Text(
'评论',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 8),
Text(
'${_comments.length}',
style: TextStyle(
fontSize: 14,
color: Color(0xFF999999),
),
),
],
),
),
],
),
),
// 评论列表
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final comment = _comments[index];
return _buildCommentItem(comment);
},
childCount: _comments.length,
),
),
SliverToBoxAdapter(
child: SizedBox(height: 80),
),
],
),
// 底部操作栏
bottomNavigationBar: _buildBottomBar(),
);
}
Widget _buildCommentItem(Map<String, dynamic> comment) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 18,
backgroundImage: NetworkImage(comment['avatar']),
),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
comment['userName'],
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
SizedBox(height: 4),
Text(
comment['content'],
style: TextStyle(
fontSize: 14,
color: Color(0xFF333333),
height: 1.4,
),
),
SizedBox(height: 8),
Row(
children: [
Text(
comment['time'],
style: TextStyle(
fontSize: 12,
color: Color(0xFF999999),
),
),
SizedBox(width: 16),
Icon(Icons.favorite_border, size: 14, color: Color(0xFF999999)),
SizedBox(width: 4),
Text(
'${comment['likes']}',
style: TextStyle(
fontSize: 12,
color: Color(0xFF999999),
),
),
],
),
],
),
),
],
),
);
}
Widget _buildBottomBar() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: Offset(0, -2),
),
],
),
child: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: [
// 评论输入框
Expanded(
child: Container(
height: 40,
decoration: BoxDecoration(
color: Color(0xFFF5F5F5),
borderRadius: BorderRadius.circular(20),
),
child: TextField(
controller: _commentController,
decoration: InputDecoration(
hintText: '说点什么...',
hintStyle: TextStyle(fontSize: 14, color: Color(0xFF999999)),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
),
onSubmitted: (_) => _postComment(),
),
),
),
SizedBox(width: 12),
// 点赞按钮
GestureDetector(
onTap: _toggleLike,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
_isLiked ? Icons.favorite : Icons.favorite_border,
color: _isLiked ? Colors.red : Color(0xFF999999),
size: 24,
),
Text(
'$_likeCount',
style: TextStyle(fontSize: 12, color: Color(0xFF999999)),
),
],
),
),
SizedBox(width: 16),
// 报名按钮
ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('报名成功!'),
backgroundColor: Color(0xFFFF6B35),
),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFFF6B35),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 10),
),
child: Text('报名'),
),
],
),
),
),
);
}
@override
void dispose() {
_commentController.dispose();
super.dispose();
}
}