Flutter中如何按条件隐藏列表项(List Tile)内容?
The error you're seeing happens because the itemBuilder in ListView.builder must return a Widget—you can't just use return; which would return null, which isn't allowed. Here are two clean solutions to fix this, with the first being the most efficient:
1. Pre-Filter the Messages (Recommended)
Instead of checking each item in the builder, filter your message list upfront to include only the messages you want to display. This reduces the number of items the ListView needs to process, improving performance, especially with large lists.
Step 1: Update Your Widget to Accept a Filter Parameter
Modify your LatestChatMessages widget to take a showGroups boolean, so you can reuse it for both DM and group views:
class LatestChatMessages extends StatelessWidget { final bool showGroups; // Add this parameter const LatestChatMessages({Key? key, required this.showGroups}) : super(key: key); // Update constructor @override Widget build(BuildContext context) { MessagesController messagesController = Get.find(); // Filter messages based on showGroups value final filteredMessages = messagesController.latestMessages.where((msgJson) { final message = LatestMessagesModelMessages.fromJson(jsonDecode(jsonEncode(msgJson))); return showGroups ? message.roomType.toString() == "group" : message.roomType.toString() != "group"; }).toList(); if (filteredMessages.isEmpty) { return Center( child: ListView( shrinkWrap: true, children: const [ Icon(CupertinoIcons.chat_bubble, size: 80), SizedBox(height: 10), Center(child: Text("You have no messages here")) ], ), ); } return GetBuilder<MessagesController>( builder: (controller) => ListView.builder( itemCount: filteredMessages.length, // Use filtered list length itemBuilder: (context, index) { final msgJson = filteredMessages[index]; if (jsonDecode(jsonEncode(msgJson))['room_link'] == null) { return Container(); } var message = LatestMessagesModelMessages.fromJson(jsonDecode(jsonEncode(msgJson))); // Rest of your existing Slidable/ListTile code remains the same return Slidable( // ... your existing code here ... ); }, ), ); } }
Step 2: Use the Widget for DMs or Groups
- To show only Direct Messages:
LatestChatMessages(showGroups: false) - To show only Group Messages:
LatestChatMessages(showGroups: true)
2. Return an Empty Widget in the Builder (Alternative)
If you prefer to keep the full list and hide items conditionally, return an empty SizedBox.shrink() instead of return; (since itemBuilder requires a Widget):
itemBuilder: (context, index) { if (jsonDecode(jsonEncode(controller.latestMessages[index]))['room_link'] == null) { return Container(); } var message = LatestMessagesModelMessages.fromJson(jsonDecode(jsonEncode(controller.latestMessages[index]))); // Hide group messages if this is the DM view if (!showGroups && message.roomType.toString() == "group") { return SizedBox.shrink(); // Empty, invisible widget } // Hide DMs if this is the group view if (showGroups && message.roomType.toString() != "group") { return SizedBox.shrink(); } // Return your ListTile/Slidable as normal return Slidable( // ... your existing code ... ); },
Note: This approach is less efficient because the ListView still iterates over all items, even the hidden ones. Use the pre-filter method for better performance.
内容的提问来源于stack exchange,提问作者tesseract

