Flutter中如何根据条件显示/隐藏ListView内的ListTile?
解决方案
1. 添加状态变量控制过滤逻辑
在你的页面State类中新增一个布尔变量,用来记录当前的过滤模式:
bool _showOnlyActive = true; // 默认只显示未归档条目
2. 添加上方切换开关
在StreamBuilder组件的上方,添加「Active/All」切换控件,让用户可以手动切换过滤模式:
Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Active'), Switch( value: _showOnlyActive, onChanged: (newValue) { setState(() { _showOnlyActive = newValue; }); }, ), const Text('All'), ], ),
3. 过滤流数据并构建列表
修改StreamBuilder的builder逻辑,在拿到流数据后根据状态变量过滤,再用过滤后的数据集渲染列表:
child: StreamBuilder( stream: _stream, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator.adaptive(); } else if (snapshot.hasError) { return Text('Error! ${snapshot.error}'); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Text('No data present!'); } // 根据当前模式过滤数据 List<Map<String, dynamic>> filteredItems = snapshot.data!; if (_showOnlyActive) { // 仅保留isArchived为false的条目(注意字段名要和你的Supabase数据一致,原代码写的是archived,这里统一为你描述的isArchived) filteredItems = filteredItems.where((item) => item['isArchived'] == false).toList(); } return ListView.builder( itemCount: filteredItems.length, itemBuilder: (context, index) { final currentItem = filteredItems[index]; return ListTile( title: Text(currentItem['name'] ?? 'Unnamed'), subtitle: currentItem['isArchived'] ? const Text('Archived') : const Text('Active'), trailing: const Icon(Icons.chevron_right), onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => TxnsByJob(currentItem['name'] ?? ''), )); }, ); }, ); }, ),
关键说明
- 确认Supabase数据中的归档字段名是
isArchived还是archived,代码已按你描述的isArchived处理,若实际为archived请替换对应字段名 - 通过
setState更新开关状态,触发UI重绘,从而重新过滤数据并更新列表 - 增加了空值判断(
??操作符),避免数据缺失引发的异常
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

