Flutter中API数据存入列表并实现姓名搜索功能求助
解决方法
1. 确认UserModel的结构正确性
首先要保证你的UserModel能正确解析接口返回的JSON数据(接口返回的data字段是用户数组),下面是标准的模型定义示例:
class UserModel { int page; int perPage; List<User> data; UserModel({required this.page, required this.perPage, required this.data}); factory UserModel.fromJson(Map<String, dynamic> json) { var userJsonList = json['data'] as List; List<User> userList = userJsonList.map((item) => User.fromJson(item)).toList(); return UserModel( page: json['page'], perPage: json['per_page'], data: userList, ); } } class User { int id; String email; String firstName; String lastName; String avatar; User({required this.id, required this.email, required this.firstName, required this.lastName, required this.avatar}); factory User.fromJson(Map<String, dynamic> json) { return User( id: json['id'], email: json['email'], firstName: json['first_name'], lastName: json['last_name'], avatar: json['avatar'], ); } // 拼接完整姓名,方便搜索 String get fullName => '$firstName $lastName'; }
2. 实现列表存储与搜索逻辑
在主页面中,我们需要维护两个列表:一个存储所有原始用户数据,另一个存储过滤后的搜索结果,配合输入控制器实现实时搜索:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; class UserSearchPage extends StatefulWidget { const UserSearchPage({super.key}); @override State<UserSearchPage> createState() => _UserSearchPageState(); } class _UserSearchPageState extends State<UserSearchPage> { late List<User> _allUsers = []; late List<User> _filteredUsers = []; final TextEditingController _searchController = TextEditingController(); @override void initState() { super.initState(); _fetchUsers(); // 监听输入变化触发搜索 _searchController.addListener(_filterUsers); } Future<void> _fetchUsers() async { final response = await http.get(Uri.parse('https://reqres.in/api/users?page=2')); if (response.statusCode == 200) { final userModel = UserModel.fromJson(json.decode(response.body)); setState(() { _allUsers = userModel.data; _filteredUsers = _allUsers; // 初始化显示全部用户 }); } else { throw Exception('加载用户数据失败'); } } // 搜索过滤核心逻辑 void _filterUsers() { final input = _searchController.text.toLowerCase().replaceAll('+', ''); setState(() { _filteredUsers = _allUsers.where((user) { final fullName = user.fullName.toLowerCase(); // 匹配规则:姓名包含输入的字符序列,支持输入带+的格式(自动去除+) return fullName.contains(input); }).toList(); }); } @override void dispose() { _searchController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('用户搜索')), body: Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: TextField( controller: _searchController, decoration: const InputDecoration( hintText: '输入姓名搜索(如r+a+b+b+i)', prefixIcon: Icon(Icons.search), border: OutlineInputBorder(), ), ), ), Expanded( child: ListView.builder( itemCount: _filteredUsers.length, itemBuilder: (context, index) { final user = _filteredUsers[index]; return ListTile( leading: CircleAvatar(backgroundImage: NetworkImage(user.avatar)), title: Text(user.fullName), subtitle: Text(user.email), ); }, ), ), ], ), ); } }
3. 关键概念梳理
- JSON与对象转换:通过
fromJson工厂方法,将接口返回的JSON字符串先转为Map,再把data数组中的每个元素转为User对象,最终存入列表。 - 双列表设计:
_allUsers存储所有原始数据,避免重复请求接口;_filteredUsers根据搜索输入动态更新,负责UI展示。 - 搜索匹配逻辑:将输入文本和用户姓名统一转为小写,同时自动去除输入中的
+符号,实现不区分大小写的模糊匹配。
内容的提问来源于stack exchange,提问作者Md. Fazle Rabbi
相关产品推荐
相关产品推荐

