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

Flutter:如何用TextField组件实现带联想结果的搜索栏

实现带联想搜索的自定义搜索栏

要实现输入时显示联想搜索结果的自定义搜索栏,你可以基于现有的TextField,通过状态管理+实时过滤数据源来完成,具体步骤和代码如下:

核心思路

  1. 用StatefulWidget管理输入内容和联想结果的状态
  2. 监听TextField的输入变化,实时过滤预设/接口返回的数据源
  3. 将TextField与联想结果列表组合在同一布局中,根据输入内容动态显示/隐藏结果

完整实现代码

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

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

  @override
  State<CustomSearchBar> createState() => _CustomSearchBarState();
}

class _CustomSearchBarState extends State<CustomSearchBar> {
  // 模拟搜索数据源(实际项目可替换为接口请求)
  final List<String> _allItems = [
    "Apple",
    "Banana",
    "Orange",
    "Apple Pie",
    "Banana Bread",
    "Orange Juice",
    "Grape",
    "Grape Juice"
  ];
  late List<String> _filteredItems;
  final TextEditingController _searchController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _filteredItems = [];
    // 监听输入变化(也可以用TextField的onChanged)
    _searchController.addListener(_filterItems);
  }

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

  // 根据输入文本过滤数据源
  void _filterItems() {
    final query = _searchController.text.toLowerCase();
    setState(() {
      if (query.isEmpty) {
        _filteredItems = [];
      } else {
        _filteredItems = _allItems
            .where((item) => item.toLowerCase().contains(query))
            .toList();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        // 你的原有搜索TextField
        SizedBox(
          height: 45,
          width: 360,
          child: TextField(
            controller: _searchController,
            style: GoogleFonts.poppins(
              color: const Color(0xff020202),
              fontSize: 20,
              fontWeight: FontWeight.w400,
              letterSpacing: 0.5,
            ),
            decoration: InputDecoration(
              filled: true,
              fillColor: const Color(0xfff1f1f1),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(8),
                borderSide: BorderSide.none,
              ),
              hintText: "Search for Items",
              hintStyle: GoogleFonts.poppins(
                  color: const Color(0xffb2b2b2),
                  fontSize: 20,
                  fontWeight: FontWeight.w400,
                  letterSpacing: 0.5,
                  decorationThickness: 6),
              prefixIcon: const Icon(Icons.search),
              prefixIconColor: Colors.black,
            ),
          ),
        ),
        // 联想搜索结果列表
        if (_filteredItems.isNotEmpty)
          Container(
            width: 360,
            margin: const EdgeInsets.only(top: 4),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(8),
              boxShadow: [
                BoxShadow(
                  color: Colors.grey.withOpacity(0.2),
                  blurRadius: 4,
                  offset: const Offset(0, 2),
                )
              ],
            ),
            child: ListView.builder(
              shrinkWrap: true,
              padding: EdgeInsets.zero,
              itemCount: _filteredItems.length,
              itemBuilder: (context, index) {
                final item = _filteredItems[index];
                return ListTile(
                  title: Text(
                    item,
                    style: GoogleFonts.poppins(fontSize: 18),
                  ),
                  onTap: () {
                    // 点击联想项后的操作:填充到搜索框/直接搜索
                    setState(() {
                      _searchController.text = item;
                      _filteredItems = [];
                    });
                    // 这里可以添加跳转搜索结果页等逻辑
                  },
                );
              },
            ),
          ),
      ],
    );
  }
}

关键说明

  • 状态管理:通过TextEditingController监听输入变化,或者直接使用TextField的onChanged回调,两种方式都能实时获取输入文本
  • 数据源过滤:将输入文本转为小写后与数据源项匹配,确保搜索不区分大小写
  • 布局控制:用if判断控制联想列表的显示,只有当输入有内容且过滤到结果时才展示,列表使用shrinkWrap: true避免占用过多空间
  • 交互优化:点击联想项后自动填充到搜索框并隐藏结果列表,也可根据需求改为直接触发搜索请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:58:21