Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter Can';t将变量的更新状态从屏幕/第1页动态传递到屏幕/第2页_Flutter_Dart_Speech To Text - Fatal编程技术网

Flutter Can';t将变量的更新状态从屏幕/第1页动态传递到屏幕/第2页

Flutter Can';t将变量的更新状态从屏幕/第1页动态传递到屏幕/第2页,flutter,dart,speech-to-text,Flutter,Dart,Speech To Text,我在屏幕1中创建了一个实例化的对象(语音),然后调用该对象的初始化方法,在这里设置错误处理(varlastError获取错误输出)。然后我使用Navigator.pushNamed将对象作为参数传递到屏幕2,在这里我调用了一些其他的语音方法 我面临的问题是,当在屏幕2中出现错误时,我无法获得错误输出,因为初始化和错误捕获是在屏幕1中定义的 到目前为止,我所尝试的: 通过GlobalKey传递lastError,但它只传递在构建屏幕2的小部件时的状态,而不是像在屏幕1中那样直接传递状态 在屏幕2中

我在屏幕1中创建了一个实例化的对象(语音),然后调用该对象的初始化方法,在这里设置错误处理(var
lastError
获取错误输出)。然后我使用
Navigator.pushNamed
将对象作为参数传递到屏幕2,在这里我调用了一些其他的语音方法

我面临的问题是,当在屏幕2中出现错误时,我无法获得错误输出,因为初始化和错误捕获是在屏幕1中定义的

到目前为止,我所尝试的:

  • 通过GlobalKey传递
    lastError
    ,但它只传递在构建屏幕2的小部件时的状态,而不是像在屏幕1中那样直接传递状态
  • 在屏幕2中添加errorHandling方法,但对象总是调用屏幕1中的errorHandling方法
  • 正在为key.currentState.lastError添加setState,但无论如何它不会动态更新
  • 我无法将初始化调用传递到第2页,因为在传递到屏幕2录制语音之前,我需要确认对象正在屏幕1中工作

    如何在屏幕2中动态更新错误,有什么建议吗

    class PassedSpeechComponent {
      stt.SpeechToText speech;
      String lastError;
      PassedSpeechComponent(this.speech, this.lastError, this.lastStatus);
    }
    
    final key = new GlobalKey<_MainPgState>();
    
    void main() {
      runApp(MaterialApp(
        title: 'Routes',
        initialRoute: '/',
        routes: {
          '/': (context) => MainPg(key: key),
          '/speech': (context) => SpeechCapturePg(),
        },
      ));
    }
    
    class MainPg extends StatefulWidget {
      MainPg({ Key key }) : super(key: key);
      @override
      _MainPgState createState() => _MainPgState();
    }
    
    // ***** SCREEN 1 ******
    class _MainPgState extends State<MainPg> {
      var lastError = "";
      var lastStatus = "";
      bool _available = false;
      stt.SpeechToText speech = stt.SpeechToText();
    
      // speech error listener of 1st screen
      void errorListener(SpeechRecognitionError error) { 
         setState(() {
          lastError = "${error.errorMsg} - ${error.permanent}";
          print('@@@ Called error listener of 1st screen @@@');
        });
        speech.stop();
      }
    
      Future<void> initSpeechState() async {
        bool available = await speech.initialize(
           onError: errorListener);
          setState(() {
          _available = available;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        if (!_available) {
          initSpeechState();
        } 
        return Scaffold(
          appBar: AppBar(
            title: Text("--"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Initializing:$_available',
                    style: TextStyle(
                      color: _available ? Colors.green : Colors.black,
                      fontSize: 15,
                    )),
                Text('isListening:${speech.isListening}',
                    style: TextStyle(
                      color: speech.isListening ? Colors.green : Colors.black,
                      fontSize: 15,
                    )),
                    Text('Error:' + lastError, // LastError alert on first screen working as intended.
                        style: TextStyle(
                          color:
                            lastError != "" ? Colors.red : Colors.black,
                            fontSize: 15,
                    )),
                Align(        
                  child: Stack(
                      alignment: AlignmentDirectional.bottomCenter,
                      children: <Widget>[
                        SizedBox(
                          width: 110.0,
                          height: 110.0,
                          child: Visibility(
                            visible: !speech.isListening,
                            child: FloatingActionButton(
                              onPressed: () {
                                if (_available) {
                                  Navigator.pushNamed(
                                    context,
                                    '/speech',
                                    arguments: {speech, errorListener, statusListener},
                                  );
                                } else {
                                  initSpeechState();
                                }
                              },
                              tooltip: 'A single tap is enough',
                              child: Icon(Icons.mic),
                            ),
                          ),
                        ),
                      ]),
                ),
              ],
            ),
          ),
          );
      }
    }
    
    // ******** SECOND SCREEN ********
    class SpeechCapturePg extends StatefulWidget {
      final String title;
    
    const SpeechCapturePg({Key key, this.title}) : super(key: key);
      @override
      _SpeechCapturePgState createState() => _SpeechCapturePgState();
    }
    
    class _SpeechCapturePgState extends State<SpeechCapturePg>
        with TickerProviderStateMixin {
      String lastWords = "";
      String lastError = "";
      
      @override
      void initState() {
        super.initState();
       
        WidgetsBinding.instance.addPostFrameCallback((_) {
          startListening(ModalRoute.of(context).settings.arguments);
        });
    
          setState(()
          {
            // Here I try to update dinamically lastError anytime 
            // last error of first screen is updated, but is not working... =(
            lastError = key.currentState.lastError;
            print("Last Error" + key.currentState.lastError);
          });
      }
    
      @override
      dispose() {
        super.dispose();
      }
    
      // This method is never called in this screen/page, just the one created in screen 1 
      void errorListener(SpeechRecognitionError error) {
        setState(() {
          print('Called in 2nd screen:'$lastError);
        });
      }
    
      
      void startListening(speech) {
        lastWords = "";
        lastError = "";    
        // 
        speech.first.listen(
          onResult: resultListener,
          cancelOnError: true,
        );
      }
    
      void resultListener(SpeechRecognitionResult result) {
        setState(() {
          lastWords = "${result.recognizedWords}";
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            backgroundColor: Colors.redAccent,
            body: Center(
                child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      Expanded(
                        flex: 30,
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child:
                            Text('$lastWords')
                      )),
                      //***** HERE I NEED TO SHOW THE ERROR REPORTED BY OBJECT *****/                        
                      Text('Error - $lastError'),
                      // **** 2ND TRY TO SHOW ERROR REPORTED IN FIRST SCREEN
                      Text('Error' + key.currentState.lastError),                  
                ])));
      }
    }
    
    
    class PassedSpeechComponent{
    stt.SpeechToText-speech;
    字符串错误;
    PassedSpeechComponent(this.speech、this.lastError、this.lastStatus);
    }
    final key=new GlobalKey();
    void main(){
    runApp(材料应用程序)(
    标题:"路线",,
    initialRoute:“/”,
    路线:{
    “/”:(上下文)=>MainPg(键:键),
    “/speech”:(上下文)=>SpeechCapturePg(),
    },
    ));
    }
    类MainPg扩展StatefulWidget{
    MainPg({Key}):超级(Key:Key);
    @凌驾
    _MainPgState createState()=>\u MainPgState();
    }
    //******屏幕1******
    类_MainPgState扩展状态{
    var lastError=“”;
    var lastStatus=“”;
    bool_available=false;
    stt.SpeechToText speech=stt.SpeechToText();
    //第一屏语音错误监听器
    void errorListener(SpeechRecognitionError错误){
    设置状态(){
    lastError=“${error.errorMsg}-${error.permanent}”;
    打印('@@@调用了第一屏幕的错误侦听器@@');
    });
    演讲。停止();
    }
    Future initSpeechState()异步{
    bool available=wait speech.initialize(
    onError:errorListener);
    设置状态(){
    _可用=可用;
    });
    }
    @凌驾
    小部件构建(构建上下文){
    如果(!\u可用){
    initSpeechState();
    } 
    返回脚手架(
    appBar:appBar(
    标题:文本(“--”),
    ),
    正文:中(
    子:列(
    mainAxisAlignment:mainAxisAlignment.center,
    儿童:[
    文本('初始化:$\u可用',
    样式:TextStyle(
    颜色:\可用?颜色。绿色:颜色。黑色,
    尺寸:15,
    )),
    Text('isListening:${speech.isListening}',
    样式:TextStyle(
    颜色:speech.isListening?颜色。绿色:颜色。黑色,
    尺寸:15,
    )),
    Text('Error:'+lastError,//第一个屏幕上的lastError警报按预期工作。
    样式:TextStyle(
    颜色:
    lastError!=“颜色。红色:颜色。黑色,
    尺寸:15,
    )),
    对齐(
    子:堆栈(
    对齐:对齐方向.bottomCenter,
    儿童:[
    大小盒子(
    宽度:110.0,
    高度:110.0,
    孩子:可见度(
    可见:!speech.isListening,
    子:浮动操作按钮(
    已按下:(){
    如果(_可用){
    Navigator.pushNamed(
    上下文
    "致辞",,
    参数:{speech,errorListener,statusListener},
    );
    }否则{
    initSpeechState();
    }
    },
    工具提示:“一次点击就足够了”,
    子:图标(Icons.mic),
    ),
    ),
    ),
    ]),
    ),
    ],
    ),
    ),
    );
    }
    }
    //*******第二屏********
    类SpeechCapturePg扩展StatefulWidget{
    最后的字符串标题;
    const SpeechCapturePg({Key-Key,this.title}):super(Key:Key);
    @凌驾
    _SpeechCapturePgState createState()=>_SpeechCapturePgState();
    }
    类_SpeechCapturePgState扩展状态
    使用TickerProviderStateMixin{
    字符串lastWords=“”;
    字符串lastError=“”;
    @凌驾
    void initState(){
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((){
    startListening(ModalRoute.of(context.settings.arguments));
    });
    设置状态()
    {
    //在这里,我尝试随时更新DINAMICALL lastError
    //第一个屏幕的最后一个错误已更新,但不起作用=(
    lastError=key.currentState.lastError;
    打印(“上次错误”+key.currentState.lastError);
    });
    }
    @凌驾
    处置{
    super.dispose();
    }
    //此屏幕/页面中从未调用此方法,仅在屏幕1中创建的方法
    void errorListener(SpeechRecognitionError错误){
    设置状态(){
    打印('在第二个屏幕中调用:'$lastError);
    });
    }
    听讲(演讲){
    lastWords=“”;
    lastError=“”;
    // 
    演讲,先听(
    onResult:resultListener,
    取消者:是的,
    );
    }
    作废结果列表器(SpeechRecognitionResult){
    设置状态(){
    lastWords=“${result.recognizedWords}