Flutter SQLite数据查询:如何仅展示匹配数据不执行else分支
问题解决:仅展示SQLite中匹配特定索引的数据
问题描述
从SQLite数据库获取数据时,希望只展示与特定Surah值匹配的内容。目前匹配的数据能正常显示,但不匹配的数据会渲染出不需要的.........文本,导致界面出现大量无效占位。
问题原因
当前代码遍历了所有数据库返回的listData条目,对不匹配的条目返回了Center(child: Text('.........')),这些条目会在ListView中占据空间,从而出现无效内容。
解决方案
方案1:提前过滤数据(推荐)
在数据加载完成后,先筛选出与widget.surah匹配的数据,再将过滤后的列表传入ListView,这样ListView只处理有效数据,避免无效占位。
修改后的代码:
SizedBox( height: 490.h, width: double.infinity, child: FutureBuilder( future: loadData(), builder: (context, snapshot) { // 过滤出匹配Surah的数据 final filteredList = listData.where((item) => item['Surah'] == widget.surah).toList(); return ListView.builder( itemCount: filteredList.length, itemBuilder: (context, index) { return Card( color: const Color(0xffaaaa55), child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(150))), child: Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon( Icons.play_circle_fill, color: Colors.white, size: 35.sp, ), Text( '(${filteredList[index]['Ayat'].toString()})', style: myStyle(size: 18.sp), ), Icon( Icons.more_vert, color: Colors.black, size: 35.sp, ), ], ), ), SizedBox( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( filteredList[index]['Arabic'].toString(), textAlign: TextAlign.center, maxLines: 2, style: GoogleFonts.adventPro( fontSize: 22.sp), ), )), SizedBox( height: 5.h, ), SizedBox( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( filteredList[index]['Translation'] .toString(), maxLines: 4, textAlign: TextAlign.center, style: TextStyle(fontSize: 15.sp), ), )), SizedBox( height: 5.h, ), Padding( padding: const EdgeInsets.all(8.0), child: Divider( color: Colors.brown, thickness: 1.sp, ), ) ], ), ), ); }, ); }, ), )
方案2:在条目构建时跳过不匹配项
如果不想提前过滤数据,可在itemBuilder中对不匹配的条目返回一个不占空间的widget(如SizedBox.shrink()),这样无效条目不会在界面上显示:
修改后的itemBuilder部分:
itemBuilder: (context, index) { int nIndex = listData[index]['Surah']; if (widget.surah != nIndex) { // 返回不占空间的widget,跳过该条目 return SizedBox.shrink(); } else { // 原有Card代码 return Card( // ... 保持原有Card内容不变 ); } }
说明
方案1更高效,因为它减少了ListView需要处理的条目数量,同时避免了不必要的widget渲染。如果数据量较大,优先选择方案1。
内容的提问来源于stack exchange,提问作者Dilo
相关产品推荐
相关产品推荐

