'setState not working anymore if page reloads

I'm using the package speech_to_text in order to create a voice recognition page.

On the first load of the page, everything seems to be right and the package works perfectly. If I go back and reopen the voice recognition page, the setState function doesnt' work anymore.

So I worked to put the code in a custom Dialog() of my CustomDialog() class that id builded from the MainPage() class. I made this in order to use a single Stateful Widget, otherwise I couldn't update the dialog content.

In this way I get the same issue, since in the app there are direct link to the MainPage(). This will rebuild the MainPage() and when I call my CustomDialog(), the setState() is not working anymore.

Here is the code:

void _listen() async {
if (!_isListening) {
  bool available = await _speech.initialize(
    finalTimeout: const Duration(seconds: 10),
    onStatus: (val) {
      print('onStatus: $val');
      if (val.contains("done")) {
        print('>> STATUS DONE');
        setState(() {
          _isListening = false;
        });
      }
    },
    onError: (val) {
      print('onError: $val');
    },
  );
  if (available) {
    finale = false;
    setState(() {
      _isListening = true;
      stop = false;
      finale = false;
    });
    _speech.listen(
      listenMode: stt.ListenMode.confirmation,
      onResult: (val) => setState(() {
        _text = val.recognizedWords;
        if (val.hasConfidenceRating && val.confidence > 0) {
          //_confidence = val.confidence;
        }
      }),
    );
  }
} else {
  setState(() {
    _isListening = false;
  });
  _speech.stop();
}

}

You can see that there is a print value: "STATUS DONE" and this works. But the setState() after that, is not working.

Any workaround?



Solution 1:[1]

The setState method is used to rebuild UI for Stateful widgets. However, when you open a dialog box, you have to keep in mind that it is itself not a stateful widget. You can use the StatefulBuilder widget to overcome this problem:

return StatefulBuilder(
      builder: (context, setState) {
        return AlertDialog(
          title: Text("Title of Dialog"),
          content: Text(contentText),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text("Cancel"),
            ),
            TextButton(
              onPressed: () {
                setState(() {
                  contentText = "Changed Content of Dialog";
                });
              },
              child: Text("Change"),
            ),
          ],
        );
      },
    );

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 That Guy