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

Flutter聊天应用中如何实现类似jQuery append的组件追加功能

解决Flutter中WebSocket聊天的消息追加问题

你的核心问题有两个:一是修改数据后未触发UI更新,二是未正确监听WebSocket的消息返回,同时用计数器管理消息列表的方式不合理。以下是修复后的完整代码:

class ChatsDetailPage extends StatelessWidget {
  const ChatsDetailPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const ChatDetailPageData();
  }
}

class ChatDetailPageData extends StatefulWidget {
  const ChatDetailPageData({super.key});

  @override
  State<StatefulWidget> createState() => _ChatDetailPageData();
}

class _ChatDetailPageData extends State<ChatDetailPageData> {
  final TextEditingController msgInput = TextEditingController();
  final WebSocketChannel _channel = WebSocketChannel.connect(
    Uri.parse('wss://echo.websocket.events'),
  );

  // 用列表存储消息,替代计数器
  final List<String> _messages = [];

  @override
  void initState() {
    super.initState();
    // 监听WebSocket返回的消息
    _channel.stream.listen((message) {
      setState(() {
        _messages.add('对方: $message');
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Someone'),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: Container(
              color: Colors.black12,
              child: ListView.builder(
                reverse: true, // 让最新消息显示在底部,符合聊天习惯
                itemCount: _messages.length,
                itemBuilder: (context, index) {
                  // 因reverse=true,需要反转索引获取正确的消息顺序
                  final message = _messages[_messages.length - 1 - index];
                  return Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                    child: Text(message),
                  );
                },
              ),
            ),
          ),
          Row(
            children: <Widget>[
              Expanded(
                child: TextFormField(
                  controller: msgInput,
                  decoration: const InputDecoration(
                    contentPadding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                    hintText: 'Enter text',
                    fillColor: Colors.white,
                    hintStyle: TextStyle(color: Colors.black26),
                  ),
                ),
              ),
              IconButton(
                icon: const Icon(
                  Icons.send,
                  color: Colors.blueAccent,
                ),
                onPressed: sendChat,
              ),
            ],
          ),
        ],
      ),
    );
  }

  void sendChat() {
    final text = msgInput.text.trim();
    if (text.isEmpty) return;

    setState(() {
      _messages.add('我: $text');
    });
    _channel.sink.add(text);
    msgInput.clear();
  }

  @override
  void dispose() {
    _channel.sink.close();
    msgInput.dispose();
    super.dispose();
  }
}

关键修改点说明:

  • 用List<String> _messages替代chatCount,实际存储每条消息内容,能准确展示聊天内容。
  • 在initState中监听_channel.stream,收到WebSocket返回的消息时,通过setState更新列表,触发UI刷新。
  • 发送消息时,先通过setState将自己的消息加入列表,再发送到WebSocket,同时清空输入框。
  • 添加ListView.builder的reverse: true属性,让最新消息显示在屏幕底部,符合常规聊天界面逻辑。
  • 所有UI更新操作都包裹在setState中,确保Flutter重新构建组件,实现类似jQuery append的动态追加效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:15:40