You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
484 lines
13 KiB
484 lines
13 KiB
import 'package:flutter/material.dart';
|
|
import 'package:dating_touchme_app/generated/assets.dart';
|
|
|
|
class FriendTab extends StatefulWidget {
|
|
const FriendTab({super.key});
|
|
|
|
@override
|
|
State<FriendTab> createState() => _FriendTabState();
|
|
}
|
|
|
|
class _FriendTabState extends State<FriendTab> with TickerProviderStateMixin {
|
|
late TabController _tabController;
|
|
|
|
// 紫色主题色
|
|
static const Color _primaryPurple = Color(0xff8E7BF6);
|
|
|
|
// 模拟数据 - 我的关注列表
|
|
final List<Map<String, dynamic>> _followList = [
|
|
{
|
|
"id": 1,
|
|
"name": "叫我大王",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"age": 30,
|
|
"location": "广州",
|
|
"gender": "female",
|
|
"isFollowed": true,
|
|
},
|
|
{
|
|
"id": 2,
|
|
"name": "林园园",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"age": 28,
|
|
"location": "深圳",
|
|
"gender": "female",
|
|
"isFollowed": true,
|
|
},
|
|
{
|
|
"id": 3,
|
|
"name": "张雪",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"age": 25,
|
|
"location": "北京",
|
|
"gender": "female",
|
|
"isFollowed": true,
|
|
},
|
|
];
|
|
|
|
// 模拟数据 - 好友列表
|
|
final List<Map<String, dynamic>> _friendList = [
|
|
{
|
|
"id": 1,
|
|
"name": "林园园",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"isOnline": true,
|
|
},
|
|
{
|
|
"id": 2,
|
|
"name": "李晖",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"isOnline": false,
|
|
},
|
|
{
|
|
"id": 3,
|
|
"name": "李哲",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"isOnline": false,
|
|
},
|
|
{
|
|
"id": 4,
|
|
"name": "李夏",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"isOnline": true,
|
|
},
|
|
{
|
|
"id": 5,
|
|
"name": "张雪",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"isOnline": false,
|
|
},
|
|
{
|
|
"id": 6,
|
|
"name": "王强",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"isOnline": true,
|
|
},
|
|
];
|
|
|
|
// 模拟数据 - 粉丝列表
|
|
final List<Map<String, dynamic>> _fansList = [
|
|
{
|
|
"id": 1,
|
|
"name": "李晖",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"age": 32,
|
|
"location": "上海",
|
|
"gender": "male",
|
|
},
|
|
{
|
|
"id": 2,
|
|
"name": "王强",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"age": 29,
|
|
"location": "杭州",
|
|
"gender": "male",
|
|
},
|
|
{
|
|
"id": 3,
|
|
"name": "李哲",
|
|
"avatar": Assets.imagesAvatarsExample,
|
|
"age": 27,
|
|
"location": "成都",
|
|
"gender": "male",
|
|
},
|
|
];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_tabController = TabController(length: 3, vsync: this, initialIndex: 0);
|
|
_tabController.addListener(() {
|
|
setState(() {});
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_tabController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
// 顶部标签栏
|
|
_buildTabBar(),
|
|
// 内容区域
|
|
Expanded(
|
|
child: TabBarView(
|
|
controller: _tabController,
|
|
physics: const NeverScrollableScrollPhysics(), // 禁用手势滑动
|
|
children: [
|
|
_buildFollowList(), // 我的关注
|
|
_buildFriendList(), // 好友
|
|
_buildFansList(), // 粉丝
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
// 构建顶部标签栏
|
|
Widget _buildTabBar() {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
const SizedBox(width: 13),
|
|
_buildTabButton("我的关注", 0),
|
|
const SizedBox(width: 16),
|
|
_buildTabButton("好友", 1),
|
|
const SizedBox(width: 16),
|
|
_buildTabButton("粉丝", 2),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 构建标签按钮
|
|
Widget _buildTabButton(String title, int index) {
|
|
final bool isSelected = _tabController.index == index;
|
|
// 根据索引设置不同的宽高
|
|
final double width = index == 0 ? 72 : 36;
|
|
final double height = index == 0 ? 42 : 21;
|
|
|
|
return GestureDetector(
|
|
onTap: () {
|
|
if (_tabController.index != index) {
|
|
_tabController.animateTo(index);
|
|
}
|
|
},
|
|
child: SizedBox(
|
|
width: width,
|
|
height: height,
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: isSelected ? _primaryPurple : Colors.white,
|
|
borderRadius: BorderRadius.circular(20),
|
|
),
|
|
alignment: Alignment.center,
|
|
child: Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: isSelected ? Colors.white : Colors.black87,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// 构建我的关注列表
|
|
Widget _buildFollowList() {
|
|
return ListView.builder(
|
|
padding: const EdgeInsets.only(top: 8),
|
|
itemCount: _followList.length,
|
|
itemBuilder: (context, index) {
|
|
final item = _followList[index];
|
|
return _buildFollowItem(item);
|
|
},
|
|
);
|
|
}
|
|
|
|
// 构建关注项
|
|
Widget _buildFollowItem(Map<String, dynamic> item) {
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
// 头像
|
|
Container(
|
|
width: 50,
|
|
height: 50,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(25),
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(25),
|
|
child: Image.asset(item["avatar"], fit: BoxFit.cover),
|
|
),
|
|
),
|
|
|
|
// 信息
|
|
Expanded(
|
|
child: Container(
|
|
margin: const EdgeInsets.only(left: 12),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Text(
|
|
item["name"],
|
|
style: const TextStyle(
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
const SizedBox(width: 4),
|
|
// 性别图标
|
|
Icon(
|
|
item["gender"] == "female" ? Icons.female : Icons.male,
|
|
size: 16,
|
|
color: item["gender"] == "female" ? Colors.pink : Colors.blue,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
"${item["age"]}岁·${item["location"]}",
|
|
style: const TextStyle(
|
|
color: Colors.grey,
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
// 已关注按钮
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
|
|
decoration: BoxDecoration(
|
|
color: Colors.grey[200],
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: const Text(
|
|
"已关注",
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 构建好友列表
|
|
Widget _buildFriendList() {
|
|
return ListView.builder(
|
|
padding: const EdgeInsets.only(top: 8),
|
|
itemCount: _friendList.length,
|
|
itemBuilder: (context, index) {
|
|
final friend = _friendList[index];
|
|
return _buildFriendItem(friend);
|
|
},
|
|
);
|
|
}
|
|
|
|
// 构建好友项
|
|
Widget _buildFriendItem(Map<String, dynamic> friend) {
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
// 头像
|
|
Stack(
|
|
children: [
|
|
Container(
|
|
width: 50,
|
|
height: 50,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(25),
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(25),
|
|
child: Image.asset(friend["avatar"], fit: BoxFit.cover),
|
|
),
|
|
),
|
|
if (friend["isOnline"] == true)
|
|
Positioned(
|
|
bottom: 0,
|
|
right: 0,
|
|
child: Container(
|
|
width: 12,
|
|
height: 12,
|
|
decoration: BoxDecoration(
|
|
color: Colors.green,
|
|
borderRadius: BorderRadius.circular(6),
|
|
border: Border.all(color: Colors.white, width: 2),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
|
|
// 信息
|
|
Expanded(
|
|
child: Container(
|
|
margin: const EdgeInsets.only(left: 12),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
friend["name"],
|
|
style: const TextStyle(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
friend["isOnline"] == true ? "在线" : "离线",
|
|
style: TextStyle(
|
|
color: friend["isOnline"] == true ? Colors.green : Colors.grey,
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
// 箭头图标
|
|
const Icon(Icons.arrow_forward_ios, size: 16, color: Colors.grey),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 构建粉丝列表
|
|
Widget _buildFansList() {
|
|
return ListView.builder(
|
|
padding: const EdgeInsets.only(top: 8),
|
|
itemCount: _fansList.length,
|
|
itemBuilder: (context, index) {
|
|
final fan = _fansList[index];
|
|
return _buildFanItem(fan);
|
|
},
|
|
);
|
|
}
|
|
|
|
// 构建粉丝项
|
|
Widget _buildFanItem(Map<String, dynamic> fan) {
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
// 头像
|
|
Container(
|
|
width: 50,
|
|
height: 50,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(25),
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(25),
|
|
child: Image.asset(fan["avatar"], fit: BoxFit.cover),
|
|
),
|
|
),
|
|
|
|
// 信息
|
|
Expanded(
|
|
child: Container(
|
|
margin: const EdgeInsets.only(left: 12),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Text(
|
|
fan["name"],
|
|
style: const TextStyle(
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
const SizedBox(width: 4),
|
|
// 性别图标
|
|
Icon(
|
|
fan["gender"] == "female" ? Icons.female : Icons.male,
|
|
size: 16,
|
|
color: fan["gender"] == "female" ? Colors.pink : Colors.blue,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
"${fan["age"]}岁·${fan["location"]}",
|
|
style: const TextStyle(
|
|
color: Colors.grey,
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
// 关注按钮
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
|
|
decoration: BoxDecoration(
|
|
color: _primaryPurple,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: const Text(
|
|
"关注",
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|