如何在Flutter中实现搜索栏,通过用户名查询Provider加载的AppUserData用户数据
Flutter搜索栏功能实现方案
核心实现逻辑
- 新增搜索文本控制器管理输入内容
- 维护过滤后的用户列表,随搜索输入和原始用户数据动态更新
- 列表直接渲染过滤后的数据集
修改后完整代码
import 'package:flutter/material.dart'; import 'package:models/user.dart'; import 'package:provider/provider.dart'; class UserList extends StatefulWidget { @override FilterLocalListPageState createState() => FilterLocalListPageState(); } class FilterLocalListPageState extends State<UserList> { // 搜索输入控制器 final TextEditingController _searchController = TextEditingController(); // 存储过滤后的用户列表 List<AppUserData> _filteredUsers = []; // 存储原始全量用户列表 List<AppUserData> _allUsers = []; @override void initState() { super.initState(); // 监听搜索输入变化,实时过滤 _searchController.addListener(_filterUsers); } @override void didChangeDependencies() { super.didChangeDependencies(); // 获取Provider提供的全量用户数据 _allUsers = Provider.of<List<AppUserData>>(context); // 初始化/用户数据更新时重新过滤 _filterUsers(); } @override void dispose() { // 释放控制器避免内存泄漏 _searchController.dispose(); super.dispose(); } // 用户过滤逻辑 void _filterUsers() { final searchKeyword = _searchController.text.toLowerCase(); if (searchKeyword.isEmpty) { // 搜索词为空时展示全部用户 setState(() { _filteredUsers = _allUsers; }); return; } setState(() { _filteredUsers = _allUsers.where((user) { return user.name.toLowerCase().contains(searchKeyword); }).toList(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("users"), centerTitle: true, ), body: Column( children: <Widget>[ // 搜索输入框 Padding( padding: const EdgeInsets.all(8.0), child: TextField( controller: _searchController, decoration: const InputDecoration( hintText: '输入用户名搜索', prefixIcon: Icon(Icons.search), border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10)), ), ), ), ), Expanded( child: ListView.builder( itemCount: _filteredUsers.length, itemBuilder: (context, index) { return buildUserItem(_filteredUsers[index]); }, ), ), ], ), ); } Widget buildUserItem(AppUserData user) => ListTile( leading: Image.network( user.profilepic, fit: BoxFit.cover, width: 50, height: 50, errorBuilder: (context, error, stackTrace) { // 图片加载失败时展示默认头像 return const Icon(Icons.account_circle, size: 50); }, ), title: Text(user.name), ); }
补充说明
- 默认实现了大小写不敏感的模糊匹配,只要用户名包含输入的搜索词就会被展示
- 新增了图片加载异常的兜底处理,避免图片加载失败导致页面报错
- 当Provider中的全量用户数据更新时,会自动触发重新过滤,保证数据同步
内容的提问来源于stack exchange,提问作者pmlo pmlo
相关产品推荐
相关产品推荐

