Android 颤振:触发websocket消息上的屏幕更改

Android 颤振:触发websocket消息上的屏幕更改,android,mobile,websocket,dart,flutter,Android,Mobile,Websocket,Dart,Flutter,我目前正在使用websocket开发一个颤振应用程序。 我想在websocket对新消息触发的方法中使用Navigator.pushNamed(context,'/path')更改当前屏幕。问题是我在这个方法中没有任何上下文 那么如何从该方法更改当前屏幕? 我不知道我是不是想错了,或者我只是不明白什么 这是一个新websocket消息触发的方法,他的类不是小部件。此对象包含在我创建的每个屏幕中,但其变量\u parent始终设置为与活动屏幕匹配 onMessageReceived(data


我目前正在使用websocket开发一个颤振应用程序。 我想在websocket对新消息触发的方法中使用
Navigator.pushNamed(context,'/path')
更改当前屏幕。问题是我在这个方法中没有任何
上下文

那么如何从该方法更改当前屏幕?
我不知道我是不是想错了,或者我只是不明白什么

这是一个新websocket消息触发的方法,他的类不是小部件。此对象包含在我创建的每个屏幕中,但其变量
\u parent
始终设置为与活动屏幕匹配

   onMessageReceived(data) {
        print("new message: " + data + " !");
        data = jsonDecode(data);
        data.forEach((key, value) {
          switch (key) {
            case "state":
              _parent.newState(value);
              break;
          }
      });
  }
以下是小部件的方法:

  newState(state){
    if(state == "start"){
      Navigator.pushNamed(, "/path");
    }
  }

提前感谢

您可以使用流来实现这一点。您可以注册websocket响应,当它返回时,您可以将其添加到流中,然后在屏幕上使用StreamBuilder订阅流并在需要时导航。大概是这样的:

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

// Create a stream to receive the values
var webSocketStream = new BehaviorSubject<String>();

onMessageReceived(data) {
  print("new message: " + data + " !");
  data = jsonDecode(data);
  data.forEach((key, value) {
    switch (key) {
      case "state":
        // Write to the stream
        webSocketStream.add(value);
        break;
    }
  });
}

class CheckWebSocket extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<String>(
          // Subscribe to the stream
          stream: webSocketStream,
          builder: (context, snapshot) {
            // When the stream changes navigate
            if (snapshot.hasData && snapshot.data == "start") {
              Navigator.pushNamed(context, "/path");
            } else {
              return Container();
            }
          }),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:rxdart/rxdart.dart”;
//创建一个流来接收这些值
var webSocketStream=new BehaviorSubject();
onMessageReceived(数据){
打印(“新消息:“+数据+”!”);
数据=jsonDecode(数据);
data.forEach((键,值){
开关(钥匙){
案例“国家”:
//写入流
webSocketStream.add(值);
打破
}
});
}
类CheckWebSocket扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:StreamBuilder(
//订阅流
流:webSocketStream,
生成器:(上下文,快照){
//当流更改时,导航
if(snapshot.hasData&&snapshot.data==“开始”){
Navigator.pushNamed(上下文,“/path”);
}否则{
返回容器();
}
}),
);
}
}

为此我使用了rxdart,因为它使处理流变得更简单。我还建议您将读取websocket的代码提取到一个单独的类中,我将所有内容都放在一个文件中,以便更容易理解。

您可以使用流。您可以注册websocket响应,当它返回时,您可以将其添加到流中,然后在屏幕上使用StreamBuilder订阅流并在需要时导航。大概是这样的:

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

// Create a stream to receive the values
var webSocketStream = new BehaviorSubject<String>();

onMessageReceived(data) {
  print("new message: " + data + " !");
  data = jsonDecode(data);
  data.forEach((key, value) {
    switch (key) {
      case "state":
        // Write to the stream
        webSocketStream.add(value);
        break;
    }
  });
}

class CheckWebSocket extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<String>(
          // Subscribe to the stream
          stream: webSocketStream,
          builder: (context, snapshot) {
            // When the stream changes navigate
            if (snapshot.hasData && snapshot.data == "start") {
              Navigator.pushNamed(context, "/path");
            } else {
              return Container();
            }
          }),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:rxdart/rxdart.dart”;
//创建一个流来接收这些值
var webSocketStream=new BehaviorSubject();
onMessageReceived(数据){
打印(“新消息:“+数据+”!”);
数据=jsonDecode(数据);
data.forEach((键,值){
开关(钥匙){
案例“国家”:
//写入流
webSocketStream.add(值);
打破
}
});
}
类CheckWebSocket扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:StreamBuilder(
//订阅流
流:webSocketStream,
生成器:(上下文,快照){
//当流更改时,导航
if(snapshot.hasData&&snapshot.data==“开始”){
Navigator.pushNamed(上下文,“/path”);
}否则{
返回容器();
}
}),
);
}
}

为此我使用了rxdart,因为它使处理流变得更简单。我还建议您将读取websocket的代码提取到单独的类中,我将所有内容都放在一个文件中,只是为了让它更容易理解。

您需要导航到其他屏幕,还是只想显示
websocket的数据?@MazinIbrahim我真的想导航到另一个屏幕。@MaëlGassmann为此,我认为您需要调用setState而不是new state来获取数据rerenderis您需要导航到其他屏幕,或者您只想显示
websocket
?@MazinIbrahim我真的想导航到另一个屏幕。@MaëlGassmann为此,我认为您需要调用setState而不是new state来获取您答案的ReRenderHand,当我在我的应用程序中实现时,我收到一个错误,因为它无法在导航之前完成构建:在构建StreamBuilder时抛出了以下断言(脏,状态:I/flatter(32357):_StreamBuilderBaseState#489bf):I/flatter(32357):在构建过程中调用了setState()或markNeedsBuild()。如果快照没有数据,我忘了返回空容器,请重试。仍然显示相同的错误。你们确定你们可以在构建过程中导航吗?无论如何,我找到了一个解决方案:若快照并没有数据,我只会显示一个和他有数据不同的支架。非常感谢。感谢您的回答,当我在我的应用程序中实现此功能时,我遇到了一个错误,因为它无法在导航之前完成构建:在构建StreamBuilder时抛出了以下断言(脏,状态:I/flatter(32357):_StreamBuilderBaseState#489bf):I/flatter(32357):setState()或markNeedsBuild()在生成过程中调用。如果快照没有数据,我忘记返回空容器,请重试。仍然显示相同的错误。你们确定你们可以在构建过程中导航吗?无论如何,我找到了一个解决方案:若快照并没有数据,我只会显示一个和他有数据不同的支架。谢谢。