You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中SearchAnchor/SearchBar的onSubmitted回调替代方案

解决Flutter SearchAnchor/SearchBar监听回车键提交搜索的问题

在Flutter 3.10.0引入的SearchAnchor/SearchBar组件中,确实没有像TextField那样直接提供onSubmitted回调,但可以通过以下两种方法检测回车键按下事件,实现关闭搜索面板并展示搜索结果的需求。

方案一:利用SearchBar的onEditingComplete与textInputAction

通过配置SearchBar的输入动作为搜索类型,再借助onEditingComplete回调响应回车键(或键盘搜索键)的触发,同时调用SearchController的closeView()关闭搜索面板。

import 'package:flutter/material.dart';

class SearchView extends StatefulWidget {
  const SearchView({super.key});

  @override
  State<SearchView> createState() => _SearchViewState();
}

class _SearchViewState extends State<SearchView> {
  final searchController = SearchController();

  @override
  void dispose() {
    searchController.dispose();
    super.dispose();
  }

  void _handleSearchSubmitted() {
    final searchText = searchController.text.trim();
    if (searchText.isNotEmpty) {
      // 此处编写你的搜索逻辑,比如跳转结果页、展示本地结果等
      print('执行搜索:$searchText');
      // 关闭搜索面板
      searchController.closeView();
    }
  }

  @override
  Widget build(BuildContext context) {
    return SearchAnchor(
      searchController: searchController,
      builder: (context, controller) {
        return SearchBar(
          onTap: () => controller.openView(),
          controller: controller,
          onChanged: (text) {
            // 处理输入内容变化的逻辑
          },
          // 设置键盘输入动作为搜索
          textInputAction: TextInputAction.search,
          // 监听编辑完成事件(回车键/搜索键触发)
          onEditingComplete: _handleSearchSubmitted,
        );
      },
      suggestionsBuilder: (context, controller) {
        return [];
      },
    );
  }
}

方案二:使用RawKeyboardListener监听键盘事件

如果需要更精细的键盘事件控制,可以用RawKeyboardListener包裹SearchBar,直接监听回车键的按下动作。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class SearchView extends StatefulWidget {
  const SearchView({super.key});

  @override
  State<SearchView> createState() => _SearchViewState();
}

class _SearchViewState extends State<SearchView> {
  final searchController = SearchController();
  final focusNode = FocusNode();

  @override
  void dispose() {
    searchController.dispose();
    focusNode.dispose();
    super.dispose();
  }

  void _handleKeyEvent(RawKeyEvent event) {
    if (event is RawKeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) {
      final searchText = searchController.text.trim();
      if (searchText.isNotEmpty) {
        print('执行搜索:$searchText');
        searchController.closeView();
        // 收起键盘
        FocusScope.of(context).unfocus();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return SearchAnchor(
      searchController: searchController,
      builder: (context, controller) {
        return RawKeyboardListener(
          focusNode: focusNode,
          onKey: _handleKeyEvent,
          child: SearchBar(
            onTap: () {
              controller.openView();
              focusNode.requestFocus();
            },
            controller: controller,
            onChanged: (text) {
              // 处理输入内容变化的逻辑
            },
          ),
        );
      },
      suggestionsBuilder: (context, controller) {
        return [];
      },
    );
  }
}

注意事项

  • 方案一的onEditingComplete会同时响应回车键和键盘上的“搜索/完成”按钮,符合常规搜索交互习惯。
  • 方案二需要注意管理FocusNode的生命周期,组件销毁时务必调用dispose()释放资源,避免内存泄漏。
  • 两种方案都建议先判断输入内容是否为空,避免触发无效搜索。

内容的提问来源于stack exchange,提问作者Giant Squid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:08:19