首页 > 解决方案 > 尽管使用 Provider 包在 notifyListeners 之后调用了消费者,但值未更新

问题描述

我期待将一个对象和一个动态值从我的第 1 页传递到我的第 2 页。我决定使用提供程序包并将我的 page1 设置为 notificationProvider。(我本可以使用我想要使用的对象创建一个独立的类,但我不想在主要使用我的对象的第 1 页中添加许多消费者)。

我面临的问题是动态值lastWords没有在 page2 中更新,尽管当变量在 page1 中更改值notifyListenersConsumer正在调用它。

任何建议我的代码可能有什么问题?

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => _MainPgState(),
      child: 
        MaterialApp(
        title: 'Routes',
        initialRoute: '/',
        routes: {
          '/': (context) => MainPg(),
          '/speech': (context) => SpeechCapturePg(),
        },   
  )));
}

class MainPg extends StatefulWidget  {
  @override
  _MainPgState createState() => _MainPgState();
}

// >>>>> PAGE 1 >>>>>
class _MainPgState extends State<MainPg> with ChangeNotifier {
  var lastError = "";   // dynamic variable to be passed to page2
  var lastStatus = "";
  bool _available = false;
  stt.SpeechToText speech = stt.SpeechToText();

  void errorListener(SpeechRecognitionError error) {
    setState(() {
      lastError = "${error.errorMsg} - ${error.permanent}";
      // >>>> Here, costumer is notified that lastError has changed.      
      notifyListeners(); });
      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('Started:$_available',
                style: TextStyle(
                  color: _available ? Colors.green : 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) {
                              // >>> Here called page2
                              Navigator.pushNamed(
                                context,
                                '/speech',
                              );
                            } else {
                              initSpeechState();
                            }},
                      ))]),
            )]), 
      ),);}
}

///>>>>>  PAGE 2
class SpeechCapturePg extends StatefulWidget {
  @override
  _SpeechCapturePgState createState() => _SpeechCapturePgState();
}

class _SpeechCapturePgState extends State<SpeechCapturePg> {

  @override
  void initState() {
    super.initState();
    startListening(context);
  }

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

  void startListening(BuildContext context) {  
    // >>> Here the speech object is used in page 2 and is working well
    context.read<_MainPgState>().speech.listen( 
      cancelOnError: true,
    );
  }
  
  @override
  Widget build(BuildContext context) {
     return Scaffold(
        backgroundColor: Colors.redAccent,     
        body: Center( 
              // >>>> Here, lastError not returning the expected value
              Consumer<_MainPgState>(
              builder: (context, object, child) => Text(
                'Error:${object.lastError}',
                    style: TextStyle(
                    color: Colors.black,
                    fontSize: 15,
                  ))
              ),    
        )
      );
  }
}

标签: flutterflutter-provider

解决方案


推荐阅读