Flutter本地JSON列表搜索功能失效,请求协助排查解决
问题排查与解决方案
你的搜索功能失效主要有以下几个核心问题,对应修复方案如下:
问题点梳理
- 搜索结果未清空:每次输入搜索词时,
searchedData没有被清空,旧结果持续累加导致数据混乱。 - 未触发UI更新:搜索逻辑执行后未调用
setState(),Flutter无法感知状态变化刷新列表。 - 重复加载数据:
FutureBuilder直接绑定_loadfile(),组件每次重建都会重复读取本地文件,浪费资源且易引发状态混乱。 - 搜索无大小写兼容:直接使用
contains匹配,大小写不一致时会匹配失败。 - 空搜索未重置显示:搜索文本清空时,未切换回显示原始的
mmaData列表。
修复步骤
- 初始化单次加载数据:在
initState中调用_loadfile(),避免重复执行文件读取操作。 - 完善搜索逻辑:
- 每次搜索前清空
searchedData - 调用
setState()触发UI更新 - 统一转小写实现大小写不敏感搜索
- 处理空搜索场景,重置显示原始数据
- 每次搜索前清空
- 用状态变量管理加载状态:替换
FutureBuilder的重复执行问题,通过_isLoading变量控制加载提示显示。
修复后的完整代码
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:io'; import './mmamodel.dart'; class ShowData extends StatefulWidget { static const routeName = '/showData'; @override State<ShowData> createState() => _ShowDataState(); } class _ShowDataState extends State<ShowData> { List<mmamodel> mmaData = <mmamodel>[]; List<mmamodel> searchedData = <mmamodel>[]; TextEditingController controller = TextEditingController(); bool _isLoading = true; // 新增加载状态变量 Future _loadfile() async { final prefs = await SharedPreferences.getInstance(); final path = prefs.getString('path'); if (path == null) { setState(() => _isLoading = false); return; } File file = File(path); final contents = await file.readAsString(); var list = json.decode(contents) as List<dynamic>; setState(() { mmaData = list.map((e) => mmamodel.fromJson(e)).toList(); _isLoading = false; }); } @override void initState() { super.initState(); _loadfile(); // 初始化时仅加载一次数据 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('MMALIST'), ), body: Column( children: [ _searchBar(), _isLoading ? const Center(child: CircularProgressIndicator()) : Expanded( child: searchedData.isEmpty ? ListView.builder( itemCount: mmaData.length, itemBuilder: (context, index) { return Text(mmaData[index].product.toString()); }, ) : ListView.builder( itemCount: searchedData.length, itemBuilder: (context, index) { return Text(searchedData[index].product.toString()); }, ), ), ], ), ); } Widget _searchBar() { return Padding( padding: const EdgeInsets.all(8), child: TextFormField( controller: controller, decoration: const InputDecoration(hintText: 'Search by product'), onChanged: onSearchTextChanged, ), ); } void onSearchTextChanged(String text) { setState(() { if (text.isEmpty) { searchedData.clear(); // 清空搜索结果,恢复显示原始数据 return; } final lowerText = text.toLowerCase(); searchedData = mmaData.where((item) { final productName = item.product?.toLowerCase() ?? ''; return productName.contains(lowerText); }).toList(); }); } }
额外优化建议
- 代码中已处理
product字段的空值判断,避免空指针异常; - 若数据量较大,可改用
ListView.separated提升滚动性能,或添加防抖逻辑(延迟500ms再执行搜索)减少频繁状态更新。
内容的提问来源于stack exchange,提问作者Raghava Reddy
相关产品推荐
相关产品推荐

