Flutter中MQTT消息转JSON及解决单索引多数据仅显示最后一条问题
问题解决方案
一、解决仅显示最后一条数据的问题
核心原因是你每次只处理了消息列表的第一条,且没有保留历史消息。需要通过维护一个消息列表来存储所有收到的数据,再动态渲染所有条目。
二、解决MQTT消息转JSON的问题
使用dart:convert包的jsonDecode方法将字符串格式的payload解析为JSON对象,即可针对字段编写条件判断逻辑。
修改后的完整代码
import 'dart:convert'; import 'package:flutter/material.dart'; // 导入你的MQTT相关包 class MqttSensorPage extends StatefulWidget { const MqttSensorPage({super.key}); @override State<MqttSensorPage> createState() => _MqttSensorPageState(); } class _MqttSensorPageState extends State<MqttSensorPage> { // 存储所有解析后的传感器JSON数据 final List<Map<String, dynamic>> _sensorDataList = []; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Flutter MQTT"), ), body: FutureBuilder( future: mqttSubscribe(topic: "/sensor_simulator/data"), builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Center( child: Text("连接错误: ${snapshot.error}"), ); } if (snapshot.connectionState == ConnectionState.done) { return StreamBuilder( stream: snapshot.data, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Center( child: Text("数据流错误: ${snapshot.error}"), ); } if (snapshot.hasData) { try { final List<MqttReceivedMessage> receiveMessages = snapshot.data; // 遍历所有收到的消息,而非仅取第一条 for (var msg in receiveMessages) { final recMess = msg.payload as MqttPublishMessage; String payload = MqttPublishPayload.bytesToStringAsString(recMess.payload.message); // 将字符串转为JSON对象 Map<String, dynamic> sensorData = jsonDecode(payload); // 加入列表(可限制长度避免内存占用过高) setState(() { _sensorDataList.add(sensorData); // 可选:只保留最近10条数据 if (_sensorDataList.length > 10) { _sensorDataList.removeAt(0); } }); } // 动态渲染所有数据条目 return ListView.builder( padding: const EdgeInsets.all(10), itemCount: _sensorDataList.length, itemBuilder: (context, index) { var data = _sensorDataList[index]; // 条件判断示例:温度超过30℃时文字变红 Color textColor = (data['temperature'] ?? 0) > 30 ? Colors.red : Colors.black; return Card( child: ListTile( title: Text("温度: ${data['temperature']}°C", style: TextStyle(color: textColor)), subtitle: Text("湿度: ${data['humidity']}% | 气压: ${data['pressure']}hPa"), ), ); }, ); } catch (e) { return Center(child: Text("解析错误: ${e.toString()}")); } } return const Center(child: CircularProgressIndicator()); }, ); } return const Center(child: CircularProgressIndicator()); }, ), ); } }
关键修改说明
- 维护消息列表:添加
_sensorDataList变量存储所有解析后的JSON数据,确保历史消息不会丢失 - 遍历所有消息:循环处理
receiveMessages中的每一条消息,而非仅取索引0的条目 - JSON解析:通过
jsonDecode将payload字符串转为Map对象,支持直接访问字段(如data['temperature']) - 条件判断示例:根据温度值动态改变文字颜色,你可以根据需求扩展更多判断逻辑
- 高效列表渲染:使用
ListView.builder替代固定ListView,优化长列表性能
内容的提问来源于stack exchange,提问作者syaf_
相关产品推荐
相关产品推荐

