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

Flutter如何基于socket.io及数据库实时数据动态修改widget颜色

你当前使用的FutureBuilder仅会在页面初始化时发起一次数据请求,无法监听socket.io推送的实时数据变更,因此无法实现动态更新效果。你需要改用StreamBuilder监听socket的实时数据流,配合状态更新实现颜色自动变更。

步骤1:在roomService中创建Socket实时数据流

首先在你的roomService类中添加Stream控制器,监听socket.io的推送事件,将收到的实时数据同步到Stream中。

import 'dart:async';
import 'package:socket_io_client/socket_io_client.dart' as IO;

class RoomService {
  // 定义Stream控制器,用于推送房间数据更新
  final StreamController<Room> _roomStreamController = StreamController<Room>.broadcast();
  late IO.Socket socket;

  // 初始化socket连接
  void initSocket() {
    socket = IO.io('你的socket服务地址', <String, dynamic>{
      'transports': ['websocket'],
      'autoConnect': false,
    });
    socket.connect();
    // 监听socket推送的房间数据更新事件,事件名需和后端保持一致
    socket.on('roomDataUpdated', (data) {
      // 将收到的json数据解析为Room对象
      Room updatedRoom = Room.fromJson(data);
      // 将新数据推送至Stream
      _roomStreamController.sink.add(updatedRoom);
    });
  }

  // 暴露Stream给外部监听
  Stream<Room> get roomStream => _roomStreamController.stream;

  // 原有获取房间数据的方法保留,用于首次加载
  Future<Room> getRoom() async {
    // 原有逻辑不变
  }

  // 页面销毁时释放资源
  void dispose() {
    socket.disconnect();
    _roomStreamController.close();
  }
}

步骤2:修改页面代码,替换FutureBuilder为StreamBuilder

将原有的FutureBuilder替换为StreamBuilder,监听roomService的实时数据流,同时根据业务规则修改Card的颜色判断逻辑:

// 首先在页面的initState中初始化socket
@override
void initState() {
  super.initState();
  roomService.initSocket();
}

@override
void dispose() {
  roomService.dispose();
  super.dispose();
}

@override
Widget build(BuildContext context) {
  return StreamBuilder<Room>(
    // 监听socket推送的实时数据流
    stream: roomService.roomStream,
    builder: (context, snapshot){
      if(snapshot.hasData){
        return GridView.builder(
          itemCount: snapshot.data!.data.length,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5),
          itemBuilder: (context, index){
            var values = snapshot.data!.data[index];
            return GestureDetector(
              onTap: (){
                Navigator.push(context, CupertinoModalPopupRoute(builder: (context)=>RoomDetailScreen(20, 30, 20+30)));
              },
              child: Card(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15.r),
                ),
                // 在这里根据业务规则判断颜色,示例:房间状态为空闲显示绿色,占用显示红色
                color: values['status'] == 'free' ? Colors.green : Colors.red,
                elevation: 6,
                child: Container(
                  alignment: Alignment.center,
                  child:Text(
                    "${values['RType']}",
                    style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: 16.sp,
                        color: AppColors.whiteSec),
                  ),
                ),
              ),
            );
          },
        );
      }else if(snapshot.hasError){
        return Center(
          child: Column(
            children: const [
              Center(child: Icon(Icons.error,color: AppColors.yellowPri,)),
            ],
          ),
        );
      }
      return const Center(child: CircularProgressIndicator());
      }
  );
}

注意事项

  • 颜色判断逻辑可根据你的实际业务字段调整,比如根据RType、占用人数等参数判断
  • 页面销毁时必须调用dispose方法释放socket和Stream资源,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:36:03