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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:43:03