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

如何在已用ListTile实现两类消息的聊天中添加第三种消息类型?

解决方案

你可以继续使用ListTile完成需求,但针对类型1的消息需要调整布局参数来实现居中显示;如果后续消息样式变得更复杂(比如不同的气泡样式),改用Row+Container的自定义布局会更灵活。以下是修改后的代码:

@override
Widget build(BuildContext context) {
  return Column(
    children: [
      Expanded(
        child: ListView.builder(
          itemCount: chats.length,
          itemBuilder: (context, index) {
            final isSelected = index == selectedIndex;
            final msg = ModelChatData.fromJson(chats[index]);
            final text = msg.text;
            final timestamp = msg.timestamp;
            final type = msg.type;
            var uid = '';
            var username = '';

            // 初始化布局相关变量
            var crossAxisAlignmentTitle = CrossAxisAlignment.start;
            var crossAxisAlignmentSubtitle = CrossAxisAlignment.start;
            Widget leadingWidget = const SizedBox.shrink();
            Widget trailingWidget = const SizedBox.shrink();
            bool showUsername = true;

            if (type == 0) { // 普通消息
              uid = msg.uid!;
              username = msg.username!;
              // 根据uid判断左右布局
              if (uid == currentUID) {
                crossAxisAlignmentTitle = CrossAxisAlignment.end;
                crossAxisAlignmentSubtitle = CrossAxisAlignment.end;
                trailingWidget = const CircleAvatar(child: FlutterLogo());
              } else {
                leadingWidget = const CircleAvatar(child: FlutterLogo());
              }
            } else if (type == 1) { // 系统消息/居中消息
              showUsername = false;
              crossAxisAlignmentTitle = CrossAxisAlignment.center;
              crossAxisAlignmentSubtitle = CrossAxisAlignment.center;
            }

            return FractionallySizedBox(
              widthFactor: 1,
              child: ListTile(
                onTap: () {
                  setState(() {
                    selectedIndex = isSelected ? null : index;
                  });
                },
                leading: leadingWidget,
                title: showUsername
                    ? Column(
                        crossAxisAlignment: crossAxisAlignmentTitle,
                        children: [
                          Text(
                            username,
                            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
                          ),
                        ],
                      )
                    : null, // 类型1消息隐藏用户名
                trailing: trailingWidget,
                subtitle: Column(
                  crossAxisAlignment: crossAxisAlignmentSubtitle,
                  children: [
                    Text(text),
                    Visibility(
                      visible: isSelected,
                      child: Text(
                        DateTime.now().toString(),
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    ],
  );
}

关键修改点:

  • 新增布局变量统一控制leading、trailing、文本对齐方式,避免重复判断
  • 类型1的消息隐藏用户名,将标题和副标题的对齐方式设为CrossAxisAlignment.center,同时清空leading和trailing组件
  • 普通消息仍按原逻辑根据uid判断左右布局

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:20:35