Files
tongxunruanjian/mobile/lib/widgets/search_box.dart
T
KIMI b95159f7eb 新增 mobile/:畅联手机端 Flutter 工程(B-58)
- 登录:工号+密码走 account-service /api/login,自动登录、被踢下线回登录页
- 消息:会话列表(未读角标/免打扰/时间)、单聊群聊、文字/语音/图片/文件消息、失败重发、历史分页
- 通讯录:新的同事/我的群聊入口、按部门分组(好友 ex 字段)、搜索
- 通话:一对一语音通话(信令走 OpenIM 自定义消息 + LiveKit,token 走 /api/rtc_token)
- 界面按确认效果图 m1/m2/m3 实现,主色 #3B87F5,四态视图齐全,无英文残留
2026-08-09 01:28:12 +08:00

68 lines
2.0 KiB
Dart

import 'package:flutter/material.dart';
import '../theme.dart';
/// 消息列表 / 通讯录共用的搜索框(效果图 m1/m3):
/// 未输入时「放大镜 + 搜索」居中显示,输入后正常左对齐。
class SearchBox extends StatefulWidget {
final ValueChanged<String> onChanged;
const SearchBox({super.key, required this.onChanged});
@override
State<SearchBox> createState() => _SearchBoxState();
}
class _SearchBoxState extends State<SearchBox> {
final TextEditingController _ctrl = TextEditingController();
@override
void dispose() {
_ctrl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: AppGap.x3, vertical: AppGap.x2),
child: Stack(
alignment: Alignment.centerLeft,
children: [
TextField(
controller: _ctrl,
onChanged: (v) {
setState(() {});
widget.onChanged(v.trim());
},
decoration: InputDecoration(
filled: true,
fillColor: AppColors.searchBg,
isDense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: AppGap.x3, vertical: AppGap.x2),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
),
),
// 空内容时的居中占位(不拦截点击,点按穿透到输入框)
if (_ctrl.text.isEmpty)
const IgnorePointer(
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.search, size: 20, color: AppColors.textSecondary),
SizedBox(width: AppGap.x1),
Text('搜索', style: TextStyle(fontSize: AppFont.sub, color: AppColors.textSecondary)),
],
),
),
),
],
),
);
}
}