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

如何使用SearchBar组件筛选Flutter中的Future<List<Room>>数据

解决方案:在Flutter Web中实现游戏房间的实时筛选

核心思路是先获取并存储所有房间数据到本地状态,再基于搜索文本对本地数据进行筛选,避免重复调用API,同时解决无法直接筛选Future的问题。

修改步骤:

  1. 调整状态变量

    • 移除原来的Future<List<Room>>? gameRooms,换成三个状态变量:
      • _allRooms:存储从API获取的所有房间,仅在初始化时赋值一次
      • _filteredRooms:存储筛选后的房间,用于UI展示
      • _isLoading:标记数据是否正在加载
  2. 重构数据获取逻辑

    • 新增_fetchGameRooms方法,调用API后将数据存入_allRooms,并初始化_filteredRooms,同时更新加载状态
  3. 实现筛选逻辑

    • 在filterRoom方法中,根据搜索文本过滤_allRooms,将结果赋值给_filteredRooms并触发UI更新
    • 加入大小写不敏感的匹配,提升用户体验
  4. 更新UI部分

    • 绑定SearchBar的onChanged到filterRoom方法
    • 替换原来的FutureBuilder,通过_isLoading判断展示加载状态或筛选后的房间列表

修改后的完整代码:

import 'package:boardhub/entities/room.dart';
import 'package:boardhub/routes/dashboard/components/room_card.dart';
import 'package:flutter/material.dart';

class Dashboard extends Stateful Widget {
  const Dashboard({super.key});

  @override
  State<Dashboard> createState() => _DashboardState();
}

class _DashboardState extends State<Dashboard> {
  List<Room> _allRooms = [];
  List<Room> _filteredRooms = [];
  bool _isLoading = true;

  Future<List<Room>> getGameRooms() async {
    await Future.delayed(const Duration(seconds: 3));
    return List<Room>.generate(48, (index) => Room(
      gameName: "Sala de jogo $index", 
      gameAddress: "Endereço $index", 
      gameDate: DateTime.now()
    ));
  }

  @override
  void initState() {
    super.initState();
    _fetchGameRooms();
  }

  Future<void> _fetchGameRooms() async {
    final rooms = await getGameRooms();
    setState(() {
      _allRooms = rooms;
      _filteredRooms = rooms;
      _isLoading = false;
    });
  }

  void filterRoom(String filterText){
    setState(() {
      if(filterText.trim().isEmpty){
        _filteredRooms = _allRooms;
      } else {
        final lowerCaseFilter = filterText.toLowerCase();
        _filteredRooms = _allRooms.where((room) => 
          room.gameName.toLowerCase().contains(lowerCaseFilter)
        ).toList();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SearchBar(
          leading: const Icon(Icons.search),
          hintText: "Dixit, Monopoly, Zombicide...",
          onChanged: filterRoom,
        ),
        _isLoading 
          ? const CircularProgressIndicator()
          : Expanded(
              child: SingleChildScrollView(
                child: Wrap(
                  spacing: 10,
                  runSpacing: 10,
                  children: [
                    const IconButton(onPressed: (){}, icon: Icon(Icons.abc)),
                    for(Room room in _filteredRooms)
                      RoomCard(room: room)
                  ]
                ),
              ),
            )
      ],
    );
  }
}

关键说明:

  • 避免重复API调用:_allRooms仅在初始化时通过_fetchGameRooms赋值一次,后续筛选完全基于本地数据
  • 实时筛选:每次搜索文本变化时,通过setState更新_filteredRooms,触发UI重新渲染
  • 大小写不敏感匹配:将搜索文本和房间名称都转为小写后再判断包含关系,让筛选更友好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:47:17