You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter聊天UI长消息溢出屏幕问题求助

解决Flutter聊天消息溢出并实现多行显示(首行带用户名)

问题原因

你用Row直接包裹用户名和消息文本时,Row默认不会自动换行,长文本会超出屏幕宽度;加上SingleChildScrollView会允许横向滚动,但这不是你要的多行显示效果,而且TextOverflow.visible无法解决Row的宽度限制问题。

解决方案

去掉SingleChildScrollView,改用Expanded(或Flexible)包裹消息文本,让文本可以在剩余空间内自动换行,同时通过crossAxisAlignment保证首行与用户名对齐。

修改后的代码如下:

主build函数(调整ListView的itemBuilder,移除ListTile的title包裹)

@override
Widget build(BuildContext context) {
  return Scaffold(
    resizeToAvoidBottomInset: true,
    appBar: AppBar(
      backgroundColor: Colors.white,
      elevation: 0.0,
      title: Text(
        'Chat',
        style: TextStyle(
            fontFamily: 'Chalet',
            fontWeight: FontWeight.w300,
            fontSize: widget.deviceWidth * 0.06),
      ),
    ),
    backgroundColor: whitePrimary,
    body: Column(
      children: [
        Expanded(
          child: ListView.builder(
              controller: _scrollController,
              itemCount: _messages.length,
              padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), // 优化显示的内边距
              itemBuilder: (BuildContext context, int index) {
                final message = _messages[index];
                final isCurrentUser =
                    message.username == _currentUserUsername;
                return _chatRow(isCurrentUser, message); // 直接返回聊天行,无需ListTile包裹
              }),
        ),
      ],
    ),
  );
}

修改后的_chatRow函数

Widget _chatRow(bool isCurrentUser, MessageResponse message) {
  if (isCurrentUser) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      crossAxisAlignment: CrossAxisAlignment.start, // 保证文本顶部对齐
      children: [
        Expanded(
          child: Align(
            alignment: Alignment.centerRight,
            child: Text(
              message.message,
              softWrap: true, // 允许自动换行
              textAlign: TextAlign.right, // 消息文本右对齐
            ),
          ),
        ),
        const SizedBox(width: 8),
        Text(
          message.username,
          style: const TextStyle(color: orangePrimary),
        ),
      ],
    );
  } else {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(message.username),
        const SizedBox(width: 8),
        Expanded(
          child: Text(
            message.message,
            softWrap: true, // 允许自动换行
          ),
        ),
      ],
    );
  }
}

关键说明

  1. 移除SingleChildScrollView:放弃横向滚动,改为让文本自动换行实现多行显示。
  2. Expanded包裹消息文本:让消息文本占据Row的剩余空间,超出宽度时自动换行。
  3. crossAxisAlignment: CrossAxisAlignment.start:保证用户名和消息文本的顶部对齐,符合聊天消息的视觉习惯。
  4. 当前用户消息右对齐:通过MainAxisAlignment.end和Align实现消息文本右对齐,用户名固定在消息右侧首行位置。
  5. 添加内边距:在ListView上添加padding,避免消息贴到屏幕边缘,提升视觉体验。

内容的提问来源于stack exchange,提问作者Geo48

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 06:26:23