Flutter ListView Builder真机无法显示,模拟器正常问题求助
Flutter真机聊天列表空白问题排查与解决方案
问题背景
使用ListView.builder实现聊天列表,Android/iOS模拟器运行正常,但发布测试后真机上ListView区域空白。其他页面采用相同格式的ListView(仅数据和样式不同)可正常显示。
相关代码
聊天列表核心代码
Expanded( child: ListView.builder( controller: _controller, itemCount: listChat.length, itemBuilder: (context, index) { return Padding( padding: EdgeInsets.only( left: 15, right: 15, top: index == 0 ? 10 : 0, bottom: 10), child: listChat.isEmpty ? Container( alignment: Alignment.center, child: Chip( backgroundColor: Colors.grey[200], side: const BorderSide( color: Color.fromARGB(255, 239, 239, 239)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)), label: TextComp( text: "Tidak ada chat", fontSize: 14, color: Colors.grey, fontWeight: FontWeight.bold, textAlign: TextAlign.left), ), ) : listChat[index]['jenis'] == "join" ? Container( alignment: Alignment.center, child: Chip( backgroundColor: Colors.grey[200], side: const BorderSide( color: Color.fromARGB(255, 239, 239, 239)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)), label: TextComp( text: listChat[index]['nama'] == null ? "Seseorang telah bergabung" : listChat[index]['nama'] + " telah bergabung", fontSize: 14, color: Colors.grey, fontWeight: FontWeight.bold, textAlign: TextAlign.left), ), ) : Row( children: [ Expanded( child: Column( crossAxisAlignment: listChat[index]['id_user'] == idUser ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ Container( child: TextComp( text: listChat[index]['nama'] == null ? "Seseorang" : listChat[index]['nama'], fontSize: 14, color: Colors.black, fontWeight: FontWeight.bold, textAlign: TextAlign.left), ), listChat[index]['jenis'] == "Materi" ? Container( margin: const EdgeInsets.only(top: 0), child: Chip( backgroundColor: Colors.grey[200], side: const BorderSide(color: Colors.teal), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)), label: TextComp( text: listChat[index]['judul'] == null ? "" : listChat[index]['judul'], fontSize: 10, color: Colors.teal, fontWeight: FontWeight.bold, textAlign: TextAlign.left), ), ) : Container(), ChipChat( onTap: () {}, text: listChat[index]['isi_chat'] == null ? "" : listChat[index]['isi_chat'], jenis: listChat[index]['jenis'], choosen: true), Container( child: TextComp( text: Moment(DateTime.parse(listChat[index]['timestamp']).toLocal()) .format('LLL'), fontSize: 12, color: Colors.grey, fontWeight: FontWeight.normal, textAlign: TextAlign.left), ), ], ), ), ], ), ); }, ), ),
ChipChat组件代码
import 'package:flutter/material.dart'; import 'package:kambiumgo/components/text.dart'; class ChipChat extends StatelessWidget { Function onTap; String text; String jenis; bool choosen; ChipChat( {super.key, required this.onTap, required this.text, required this.jenis, required this.choosen}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(right: 0), child: GestureDetector( onTap: () { onTap(); }, child: Container( constraints: BoxConstraints( minWidth: 0, maxWidth: MediaQuery.of(context).size.width * 0.8), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), border: Border.all( color: choosen ? jenis == "Materi" ? Colors.blueAccent : Colors.teal : const Color.fromARGB(255, 239, 239, 239), ), color: choosen ? jenis == "Materi" ? Colors.blueAccent : Colors.teal : const Color.fromARGB(255, 239, 239, 239), ), child: Wrap( children: [ TextComp( text: text, fontSize: 14, color: choosen ? Colors.white : Colors.black, fontWeight: FontWeight.bold, textAlign: TextAlign.left, ), ], ), ), ), ); } }
排查方向与解决方案
1. 空列表逻辑错误(核心问题)
原代码中itemCount: listChat.length,当listChat为空时,itemCount为0,itemBuilder不会执行,导致空状态的Container永远无法渲染,真机上若数据未加载成功则直接空白。
修复方案:将空列表判断移到ListView.builder外部:
Expanded( child: listChat.isEmpty ? Container( alignment: Alignment.center, child: Chip( backgroundColor: Colors.grey[200], side: const BorderSide(color: Color.fromARGB(255, 239, 239, 239)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(100)), label: TextComp( text: "Tidak ada chat", fontSize: 14, color: Colors.grey, fontWeight: FontWeight.bold, textAlign: TextAlign.left), ), ) : ListView.builder( controller: _controller, itemCount: listChat.length, itemBuilder: (context, index) { // 原itemBuilder逻辑(去掉listChat.isEmpty判断) }, ), )
2. DateTime.parse的异常风险
发布模式下,若timestamp格式不符合预期,DateTime.parse会抛出异常导致UI渲染失败,模拟器可能因测试数据格式规范未暴露问题。
修复方案:添加异常捕获,或确保时间格式兼容:
// 替换原时间格式化代码 String formatTimestamp(String timestamp) { try { final date = DateTime.parse(timestamp).toLocal(); // 改用intl包的DateFormat替代moment库,避免第三方库兼容问题 return DateFormat('LLL').format(date); } catch (e) { return ""; // 或默认提示文本 } }
3. 第三方库兼容问题
Moment库在发布模式下可能存在优化或兼容性问题,建议替换为Flutter官方推荐的intl包处理时间格式化。
步骤:
- 添加依赖:
pubspec.yaml中加入intl: ^0.18.1 - 导入:
import 'package:intl/intl.dart'; - 使用
DateFormat替代Moment
4. 组件类型与渲染问题
ChipChat中的onTap参数类型为Function,建议改为VoidCallback以避免类型不匹配:VoidCallback onTap; // 替换原Function类型- 检查
TextComp组件在发布模式下的渲染逻辑,确保字体、样式无异常,可临时替换为原生Text组件测试是否恢复显示。
内容的提问来源于stack exchange,提问作者Haksatrya Bhaswara
相关产品推荐
相关产品推荐

