Flutter实现搜索栏无搜索效果,无法正常查询JSON数据源内容
现有代码核心问题
- 全量数据源
newData是FutureBuilder回调内的局部变量,搜索逻辑无法持久访问完整原始数据,且每次FutureBuilder重建都会重复向notesForDisplay添加数据导致条目重复 - 搜索逻辑中出现未定义的
index变量,note[index]['VERB']写法错误,应该直接取当前遍历项的VERB字段 - ListView的itemBuilder直接使用原始
newData的下标取值,未使用过滤后的notesForDisplay,导致过滤结果不会生效 - AppBar初始化时JSON数据还未加载完成,传入_searchBar的newData是空值,搜索功能无可用数据源
- 未处理FutureBuilder的加载状态,数据加载完成前会出现空指针报错
修正实现方案
第一步:在State类中定义成员变量存储数据源
class _YourPageState extends State<YourPage> { // 存储全量原始JSON数据 List _allNotes = []; // 存储当前需要展示的过滤后数据 List _notesForDisplay = []; // 你的原有变量 List<String> savedWords = []; // 后面是你的其他方法 }
第二步:调整build方法逻辑
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( automaticallyImplyLeading: true, title: _searchBar(), ), body: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/gradient_blue.jpg'), fit: BoxFit.cover ) ), child: FutureBuilder( future: DefaultAssetBundle.of(context).loadString('files/myfile.json'), builder: (context, snapshot) { // 先处理加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return const Center(child: Text("数据加载失败")); } // 仅第一次加载完成时赋值全量数据,避免重复添加 if (_allNotes.isEmpty) { _allNotes = json.decode(snapshot.data.toString()); _notesForDisplay = List.from(_allNotes); } return ListView.builder( itemBuilder: (BuildContext context, int index){ // 所有取值从过滤后的_notesForDisplay取 String word = _notesForDisplay[index]['VERB']; String meaning = _notesForDisplay[index]['MEANING']; bool isSaved = savedWords.contains(word); return _listItem(index, isSaved, word, meaning); }, itemCount: _notesForDisplay.length ); }, ), ) ) ); }
第三步:修正搜索栏逻辑
Widget _searchBar() { return Padding( padding: const EdgeInsets.all(8.0), child: TextField( decoration: InputDecoration(hintText: 'Search..'), onChanged: (text) { text = text.toLowerCase(); setState(() { if (text.isEmpty) { // 搜索内容为空时重置展示全部数据 _notesForDisplay = List.from(_allNotes); return; } // 基于全量数据源过滤,移除错误的index引用 _notesForDisplay = _allNotes.where((note) { var noteTitle = note['VERB'].toLowerCase(); return noteTitle.contains(text); }).toList(); }); }, ), ); }
第四步:调整列表项方法参数
Widget _listItem(int index, bool isSaved, String word, String meaning) { return Card( children: <Widget>[ Column( children: <Widget>[ InkWell( child: RichText( text: TextSpan( children: [ TextSpan( text: word, // 你的其他样式配置 ) ] ) ) ) ] ) ] ); }
内容的提问来源于stack exchange,提问作者Lash
相关产品推荐
相关产品推荐

