Flutter移动端关闭默认SearchView时如何取消SearchBar焦点?
问题修复方案
针对你遇到的两个SearchBar焦点问题,可通过以下步骤解决:
核心修复思路
- 用
FocusNode管理SearchBar的焦点状态,在搜索视图关闭时主动取消焦点 - 同时处理自定义返回按钮和系统返回键的场景,确保焦点状态同步更新
修改后的完整代码
class _AddressSearchBarState extends State<AddressSearchBar> { // 初始化FocusNode用于管理搜索框焦点 final FocusNode _searchFocusNode = FocusNode(); SearchController? _searchController; @override void dispose() { // 页面销毁时释放资源 _searchFocusNode.dispose(); _searchController?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(20.0), child: WillPopScope( // 拦截系统返回键事件 onWillPop: () async { if (_searchController?.isOpen ?? false) { // 关闭搜索视图并取消焦点 _searchController?.closeView(null); _searchFocusNode.unfocus(); return false; // 阻止默认页面返回行为 } return true; }, child: SearchAnchor( isFullScreen: false, viewLeading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { _searchController?.closeView(null); // 点击返回按钮时主动取消搜索框焦点 _searchFocusNode.unfocus(); }, color: Colors.black, ), // 监听搜索视图关闭事件,确保焦点被取消 onViewClosed: () { _searchFocusNode.unfocus(); }, builder: (BuildContext context, SearchController controller) { _searchController = controller; return SearchBar( autoFocus: false, focusNode: _searchFocusNode, // 绑定FocusNode到搜索框 hintText: "Looking for an Address?", padding: const MaterialStatePropertyAll<EdgeInsets>( EdgeInsets.symmetric(horizontal: 16.0) ), onTap: () { controller.openView(); }, onChanged: (_) { controller.openView(); }, leading: const Icon(Icons.search), ); }, suggestionsBuilder: (context, controller) => [], // 后续填充Google Maps建议内容 ), ), ); } }
关键修改点说明
- FocusNode绑定:在State中初始化
_searchFocusNode并绑定到SearchBar的focusNode参数,统一管理焦点状态 - 自定义返回按钮处理:点击返回箭头时,先关闭搜索视图,再主动调用
unfocus()取消焦点,确保键盘收起 - 视图关闭监听:通过
SearchAnchor的onViewClosed回调,覆盖所有视图关闭场景(包括代码触发关闭),强制取消焦点 - 系统返回键拦截:用
WillPopScope捕获返回事件,若搜索视图处于打开状态,优先关闭视图并取消焦点,避免键盘反复唤起
内容的提问来源于stack exchange,提问作者Ahmed Shaikh
相关产品推荐
相关产品推荐

