Search code examples
androidfluttersetstateandroid-snackbar

Flutter : SetState() updates values but does not render on the screen. This happens only when using the updated values inside a Flushbar


I have a text field inside a Flushbar, and the text field makes use of Google Places API to search for places, based on the provided input. I am calling a function on the 'onChanged' parameter of the text field, as can be seen in the code, but this does not show on the screen as something is typed in the text field. Although printing the values shows that the values were updated. Additionally, on popping the Flushbar and opening it back shows the expected result.

Also, this happens only when using the updated values inside a Flushbar. It renders as expected on the scaffold.

I know this is similar to other questions that have been asked before, but no answers provided yet seem to work for me. I have even come to discover that this could be happening as the Flushbar itself does not have a 'state' and so 'setState()' does not affect its' contents. But I don't know how to go around the problem. Any help on this will be highly appreciated.

Update: I have tried using a StatefulBuilder widget inside the Flushbar but it gives similar results. I called StaefulBuilder in the return statement after the ListView.builder inside the Flushbar.

Sample Code:

@override
 Widget build (BuildContext context){
  return Scaffold(
    body : FlatButton(
      child : Text('Search Location'),
      onPressed : Flushbar(
        flushbarPosition: FlushbarPosition.BOTTOM,
        userInputForm : Form(
          child : Container(
           child : Column(
            children : <Widget>[ 
             getSearchFieldFlushBar(),
             _displaySearchedPlaces.length != 0 
               ? ListView.builder(
                   shrinkWrap : true,
                   itemCount : _displaySearchedPlaces.length
                   itemBuilder : (BuildContext context, index){

                     return ListTile(
                       title : Text(_displaySearchedPlaces[index])
                     );
                    }) 
                : Container(height : 0, width : 0),
              ])
             )
           )
          )..show(context);
         ));
        }

Here's the function, which calls the text field:

TextFormField getSearchFieldFlushbar(){
 return TextFormField(
  style: TextStyle(color: Colors.black),        
  onChanged: (text) {
    getLocationResults(text);
  },
);
    

And this is the function that gets called when something is entered in the text field:

  void getLocationResults(String input) async {

    String baseURL = 'https://maps.googleapis.com/maps/api/place/autocomplete/json';
    String type = 'geocode';

    String request = '$baseURL?input=$input&key=$places_Api_Key&type=$type';
    Response response = await Dio().get(request);

        final predictions = response.data['predictions'];

        _displayResults = [];

        for (int i = 0; i < predictions.length; i++) {
          String name = predictions[i]['structured_formatting']['main_text'];
          _displayResults.add(name);
        }

        setState(() {
          _displaySearchedPlaces = _displayResults;
        });
        
         print(_searchedPlacesResults);
       }
     }

Screenshot1 ScreenShot2


Solution

  • I finally managed to fix this using a few answers that have been given before to similar questions on Stackoverflow such as here and here.

    Basically, we use a StatefulBuilder Widget and put all the children widgets which can potentially be updated, inside this widget. As has been mentioned in the question, using this was not working for me initially, however, it started working after a while.

    For reference, I added the StatfulBuilder widget at the 'child' parameter of the Form widget.