flutter/lib/pages/groupChat/index.dart

220 lines
6.2 KiB
Dart
Raw Normal View History

2025-09-03 11:25:31 +08:00
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
class StartGroupChatPage extends StatefulWidget {
const StartGroupChatPage({super.key});
@override
State<StartGroupChatPage> createState() => _StartGroupChatPageState();
}
class _StartGroupChatPageState extends State<StartGroupChatPage> {
final TextEditingController _searchController = TextEditingController();
List<Map<String, dynamic>> dataList = [];
List<Map<String, dynamic>> filteredList = [];
Set<String> selectedIds = {}; // 已选中的用户 id
int page = 1;
bool hasMore = true;
@override
void initState() {
super.initState();
_loadData(reset: true);
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
Future<void> _loadData({bool reset = false}) async {
if (reset) {
page = 1;
hasMore = true;
dataList.clear();
}
// 模拟网络请求
await Future.delayed(const Duration(seconds: 1));
List<Map<String, dynamic>> newItems = List.generate(
10,
(index) => {"nickName": "用户 ${(page - 1) * 10 + index + 1}", "id": "${page}_$index"},
);
if (newItems.isEmpty) {
hasMore = false;
} else {
dataList.addAll(newItems);
page++;
}
_applySearch(_searchController.text);
}
void _applySearch(String query) {
setState(() {
if (query.isEmpty) {
filteredList = List.from(dataList);
} else {
filteredList = dataList.where((item) => item["nickName"].toString().contains(query.trim())).toList();
}
});
}
void _toggleSelection(String id) {
setState(() {
if (selectedIds.contains(id)) {
selectedIds.remove(id);
} else {
selectedIds.add(id);
}
});
}
Widget _buildCard({
required IconData icon,
required String title,
required VoidCallback onTap,
}) {
return Card(
color: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: ListTile(
leading: Icon(icon, color: Colors.black),
title: Text(title, style: const TextStyle(fontSize: 16)),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: onTap,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
// backgroundColor: Colors.white,
centerTitle: true,
forceMaterialTransparency: true,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1.0),
child: Container(
color: Colors.grey[300],
height: 1.0,
),
),
title: const Text(
"创建群聊",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
body: Column(
children: [
// 上半部分 - 两个卡片
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
_buildCard(
icon: Icons.public,
title: "创建公开群",
onTap: () {
print("跳转到 创建公开群");
},
),
_buildCard(
icon: Icons.group,
title: "创建好友群",
onTap: () {
print("跳转到 创建好友群");
},
),
],
),
),
const Divider(),
// 下半部分 - 搜索框 + 列表
Expanded(
child: Column(
children: [
// 搜索框
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: "搜索用户昵称",
prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
onChanged: _applySearch,
),
),
// 列表
Expanded(
child: EasyRefresh(
onRefresh: () async => _loadData(reset: true),
onLoad: () async {
if (hasMore) await _loadData();
},
child: ListView.builder(
itemCount: filteredList.length,
itemBuilder: (context, index) {
final item = filteredList[index];
final id = item["id"] as String;
final isSelected = selectedIds.contains(id);
return ListTile(
leading: CircleAvatar(
child: Text(item["nickName"].substring(0, 1)),
),
title: Text(item["nickName"]),
trailing: Checkbox(
value: isSelected,
onChanged: (_) => _toggleSelection(id),
),
onTap: () => _toggleSelection(id),
);
},
),
),
),
],
),
),
],
),
// 底部按钮
bottomNavigationBar: SafeArea(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ElevatedButton(
onPressed: selectedIds.isEmpty
? null
: () {
print("选择了用户:$selectedIds");
},
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(50),
backgroundColor: selectedIds.isEmpty ? Colors.grey : Colors.blue,
),
child: const Text(
"发起聊天",
style: TextStyle(fontSize: 16),
),
),
),
),
);
}
}