370 lines
11 KiB
Dart
370 lines
11 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
|
import 'publish_screen.dart';
|
|
import 'activity_detail_screen.dart';
|
|
import 'friends_screen.dart';
|
|
import 'dart:math';
|
|
|
|
class ActivityListScreen extends StatefulWidget {
|
|
@override
|
|
_ActivityListScreenState createState() => _ActivityListScreenState();
|
|
}
|
|
|
|
class _ActivityListScreenState extends State<ActivityListScreen> {
|
|
int _selectedIndex = 0;
|
|
|
|
// 模拟活动数据
|
|
final List<Map<String, dynamic>> activities = [
|
|
{
|
|
'title': '周末公园太极拳',
|
|
'location': '人民公园',
|
|
'participants': 12,
|
|
'image': 'https://picsum.photos/seed/1/400/300',
|
|
'creator': '王阿姨',
|
|
'avatarSeed': 11,
|
|
},
|
|
{
|
|
'title': '社区书法班开课啦',
|
|
'location': '社区活动中心',
|
|
'participants': 8,
|
|
'image': 'https://picsum.photos/seed/2/400/500',
|
|
'creator': '李老师',
|
|
'avatarSeed': 22,
|
|
},
|
|
{
|
|
'title': '广场舞队招新',
|
|
'location': '中央广场',
|
|
'participants': 25,
|
|
'image': 'https://picsum.photos/seed/3/400/400',
|
|
'creator': '张姐',
|
|
'avatarSeed': 33,
|
|
},
|
|
{
|
|
'title': '老年摄影兴趣小组',
|
|
'location': '文化馆',
|
|
'participants': 15,
|
|
'image': 'https://picsum.photos/seed/4/400/350',
|
|
'creator': '陈叔',
|
|
'avatarSeed': 44,
|
|
},
|
|
{
|
|
'title': '周三棋牌活动',
|
|
'location': '社区会所',
|
|
'participants': 20,
|
|
'image': 'https://picsum.photos/seed/5/400/450',
|
|
'creator': '赵大哥',
|
|
'avatarSeed': 55,
|
|
},
|
|
{
|
|
'title': '健康养生讲座',
|
|
'location': '图书馆',
|
|
'participants': 30,
|
|
'image': 'https://picsum.photos/seed/6/400/380',
|
|
'creator': '刘阿姨',
|
|
'avatarSeed': 66,
|
|
},
|
|
];
|
|
|
|
void _onItemTapped(int index) {
|
|
if (index == 2) {
|
|
// 中间按钮 - 跳转到发布页面
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(builder: (context) => PublishScreen()),
|
|
);
|
|
return;
|
|
}
|
|
if (index == 1) {
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(builder: (context) => const FriendsScreen()),
|
|
);
|
|
return;
|
|
}
|
|
setState(() {
|
|
_selectedIndex = index;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFFFFF8F0),
|
|
appBar: AppBar(
|
|
title: Text('伴享', style: TextStyle(fontWeight: FontWeight.bold)),
|
|
centerTitle: true,
|
|
actions: [
|
|
IconButton(
|
|
icon: Icon(Icons.search),
|
|
onPressed: () {},
|
|
),
|
|
IconButton(
|
|
icon: Icon(Icons.notifications_none),
|
|
onPressed: () {},
|
|
),
|
|
],
|
|
),
|
|
body: _buildBody(),
|
|
bottomNavigationBar: _buildBottomNavigationBar(),
|
|
floatingActionButton: _buildFloatingActionButton(),
|
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
|
);
|
|
}
|
|
|
|
Widget _buildBody() {
|
|
return RefreshIndicator(
|
|
onRefresh: () async {
|
|
await Future.delayed(Duration(seconds: 1));
|
|
setState(() {});
|
|
},
|
|
child: Padding(
|
|
padding: EdgeInsets.all(8),
|
|
child: MasonryGridView.count(
|
|
crossAxisCount: 2,
|
|
mainAxisSpacing: 8,
|
|
crossAxisSpacing: 8,
|
|
itemCount: activities.length,
|
|
itemBuilder: (context, index) {
|
|
return _buildActivityCard(activities[index]);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildActivityCard(Map<String, dynamic> activity) {
|
|
final random = Random(activity['title'].hashCode);
|
|
final height = 200.0 + random.nextInt(100);
|
|
|
|
return GestureDetector(
|
|
onTap: () {
|
|
// 跳转到详情页
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => ActivityDetailScreen(activity: activity),
|
|
),
|
|
);
|
|
},
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(12),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.08),
|
|
blurRadius: 8,
|
|
offset: Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// 封面图片
|
|
ClipRRect(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
|
|
child: Container(
|
|
height: height,
|
|
width: double.infinity,
|
|
color: Colors.grey[200],
|
|
child: Stack(
|
|
children: [
|
|
Center(
|
|
child: Icon(Icons.image, size: 40, color: Colors.grey[400]),
|
|
),
|
|
Image.network(
|
|
activity['image'],
|
|
height: height,
|
|
width: double.infinity,
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Container(
|
|
color: Colors.grey[200],
|
|
child: Center(
|
|
child: Icon(Icons.image, size: 40, color: Colors.grey[400]),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
// 标题和信息
|
|
Padding(
|
|
padding: EdgeInsets.all(12),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
activity['title'],
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: Color(0xFF333333),
|
|
),
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
SizedBox(height: 8),
|
|
Row(
|
|
children: [
|
|
Icon(Icons.location_on, size: 14, color: Color(0xFF999999)),
|
|
SizedBox(width: 4),
|
|
Expanded(
|
|
child: Text(
|
|
activity['location'],
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: Color(0xFF999999),
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 4),
|
|
Row(
|
|
children: [
|
|
Icon(Icons.people, size: 14, color: Color(0xFF999999)),
|
|
SizedBox(width: 4),
|
|
Text(
|
|
'${activity['participants']}人报名',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: Color(0xFF999999),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 8),
|
|
Row(
|
|
children: [
|
|
SizedBox(
|
|
width: 24,
|
|
height: 24,
|
|
child: ClipOval(
|
|
child: Image.network(
|
|
'https://i.pravatar.cc/50?img=${activity['avatarSeed']}',
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Container(
|
|
color: Colors.grey[200],
|
|
child: Icon(Icons.person, size: 14, color: Colors.grey[500]),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 8),
|
|
Expanded(
|
|
child: Text(
|
|
activity['creator'],
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: Color(0xFF999999),
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildBottomNavigationBar() {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.05),
|
|
blurRadius: 10,
|
|
offset: Offset(0, -2),
|
|
),
|
|
],
|
|
),
|
|
child: SafeArea(
|
|
child: Container(
|
|
height: 60,
|
|
child: Row(
|
|
children: [
|
|
_buildNavItem(0, Icons.home, '首页'),
|
|
_buildNavItem(1, Icons.people, '好友'),
|
|
SizedBox(width: 60), // 中间按钮占位
|
|
_buildNavItem(3, Icons.message, '消息'),
|
|
_buildNavItem(4, Icons.person, '我的'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildNavItem(int index, IconData icon, String label) {
|
|
final isSelected = _selectedIndex == index;
|
|
return Expanded(
|
|
child: GestureDetector(
|
|
onTap: () => _onItemTapped(index),
|
|
behavior: HitTestBehavior.opaque,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
icon,
|
|
color: isSelected ? Color(0xFFFF6B35) : Color(0xFF999999),
|
|
size: 24,
|
|
),
|
|
SizedBox(height: 4),
|
|
Text(
|
|
label,
|
|
style: TextStyle(
|
|
fontSize: 11,
|
|
color: isSelected ? Color(0xFFFF6B35) : Color(0xFF999999),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildFloatingActionButton() {
|
|
return Container(
|
|
width: 56,
|
|
height: 56,
|
|
margin: EdgeInsets.only(top: 30),
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
gradient: LinearGradient(
|
|
colors: [Color(0xFFFF6B35), Color(0xFFFFB84D)],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Color(0xFFFF6B35).withOpacity(0.4),
|
|
blurRadius: 12,
|
|
offset: Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: Material(
|
|
color: Colors.transparent,
|
|
child: InkWell(
|
|
onTap: () => _onItemTapped(2),
|
|
customBorder: CircleBorder(),
|
|
child: Icon(Icons.add, color: Colors.white, size: 28),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|