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