flutter如何实现text_search功能

在Flutter中如何实现文本搜索功能?我想在应用中添加一个搜索框,用户输入关键词后能实时过滤并显示匹配的列表项。目前使用TextField监听输入变化,但不确定如何高效处理大量数据的搜索匹配,以及如何优化性能避免卡顿。是否有推荐的做法或现成的插件可以实现这个功能?最好能支持模糊搜索和高亮显示匹配文本。

2 回复

Flutter中实现文本搜索功能,可通过以下步骤:

  1. 使用TextField获取用户输入。
  2. 使用ListView.builderListView.separated构建列表。
  3. onChanged回调中过滤数据,更新列表显示匹配项。
  4. 使用contains或正则表达式进行匹配。

更多关于flutter如何实现text_search功能的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现文本搜索功能,可以通过以下几种方式:

1. 使用TextField和List过滤

class TextSearchExample extends StatefulWidget {
  @override
  _TextSearchExampleState createState() => _TextSearchExampleState();
}

class _TextSearchExampleState extends State<TextSearchExample> {
  final List<String> items = [
    'Apple', 'Banana', 'Orange', 'Grape', 'Mango',
    'Pineapple', 'Strawberry', 'Watermelon'
  ];
  
  List<String> filteredItems = [];
  TextEditingController searchController = TextEditingController();

  @override
  void initState() {
    super.initState();
    filteredItems = items;
    searchController.addListener(_filterItems);
  }

  void _filterItems() {
    final query = searchController.text.toLowerCase();
    setState(() {
      filteredItems = items.where((item) {
        return item.toLowerCase().contains(query);
      }).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('文本搜索示例'),
      ),
      body: Column(
        children: [
          Padding(
            padding: EdgeInsets.all(16),
            child: TextField(
              controller: searchController,
              decoration: InputDecoration(
                labelText: '搜索',
                prefixIcon: Icon(Icons.search),
                border: OutlineInputBorder(),
              ),
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: filteredItems.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(filteredItems[index]),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

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

2. 使用SearchDelegate实现系统搜索

class CustomSearchDelegate extends SearchDelegate {
  final List<String> items = [
    'Apple', 'Banana', 'Orange', 'Grape', 'Mango',
    'Pineapple', 'Strawberry', 'Watermelon'
  ];

  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(
        icon: Icon(Icons.clear),
        onPressed: () {
          query = '';
        },
      ),
    ];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: Icon(Icons.arrow_back),
      onPressed: () {
        close(context, null);
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    final List<String> searchResults = items.where((item) {
      return item.toLowerCase().contains(query.toLowerCase());
    }).toList();

    return ListView.builder(
      itemCount: searchResults.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(searchResults[index]),
        );
      },
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final List<String> suggestionList = query.isEmpty
        ? []
        : items.where((item) {
            return item.toLowerCase().contains(query.toLowerCase());
          }).toList();

    return ListView.builder(
      itemCount: suggestionList.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(suggestionList[index]),
          onTap: () {
            query = suggestionList[index];
            showResults(context);
          },
        );
      },
    );
  }
}

// 使用方式
IconButton(
  icon: Icon(Icons.search),
  onPressed: () {
    showSearch(
      context: context,
      delegate: CustomSearchDelegate(),
    );
  },
)

3. 添加搜索高亮显示

Text _buildHighlightedText(String text, String query) {
  if (query.isEmpty) return Text(text);
  
  final matches = query.toLowerCase().allMatches(text.toLowerCase());
  final List<TextSpan> spans = [];
  int currentIndex = 0;

  for (final match in matches) {
    if (match.start > currentIndex) {
      spans.add(TextSpan(
        text: text.substring(currentIndex, match.start),
        style: TextStyle(color: Colors.black),
      ));
    }
    
    spans.add(TextSpan(
      text: text.substring(match.start, match.end),
      style: TextStyle(
        color: Colors.blue,
        fontWeight: FontWeight.bold,
      ),
    ));
    
    currentIndex = match.end;
  }
  
  if (currentIndex < text.length) {
    spans.add(TextSpan(
      text: text.substring(currentIndex),
      style: TextStyle(color: Colors.black),
    ));
  }
  
  return RichText(text: TextSpan(children: spans));
}

主要特点:

  • 实时搜索:使用TextField监听实现即时过滤
  • 系统集成:SearchDelegate提供原生搜索体验
  • 高亮显示:突出显示匹配的文本部分
  • 性能优化:对于大数据集建议使用异步搜索

选择哪种方式取决于你的具体需求:简单的列表过滤使用第一种,需要系统级搜索体验使用第二种。

回到顶部