Flutter - setState not updating inner Stateful Widget

Related searches

Basically I am trying to make an app whose content will be updated with an async function that takes information from a website, but when I do try to set the new state, it doesn't reload the new content. If I debug the app, it shows that the current content is the new one, but after "rebuilding" the whole widget, it doesn't show the new info.

Edit: loadData ( ) method, basically read a URL with http package, the URL contains a JSON file whose content changes every 5 minutes with new news. For example a .json file with sports real-time scoreboards whose scores are always changing, so the content should always change with new results.

class mainWidget extends StatefulWidget
{    
  State<StatefulWidget> createState() => new mainWidgetState();
}

class mainWidgetState extends State<mainWidget>
{

  List<Widget> _data;
  Timer timer;

  Widget build(BuildContext context) {
     return new ListView(
              children: _data);
  }

  @override
  void initState() {
    super.initState();
    timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
      String s = await loadData();
      this.setState(() {
        _data = <Widget> [new childWidget(s)];
      });
      });
  }
}

class childWidget extends StatefulWidget {
  childWidget(String s){
    _title = s;
  }

  Widget _title;

  createState() => new childState();
}

class childState extends State<gameCardS> {

  Widget _title;

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(onTap: foo(),
       child: new Card(child: new Text(_title));

  }

  initState()
  {
    super.initState();
    _title = widget._title;
  }
}

This should sort your problem out. Basically you always want your Widgets created in your build method hierarchy.

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(new MaterialApp(home: new Scaffold(body: new MainWidget())));

class MainWidget extends StatefulWidget {
    @override
    State createState() => new MainWidgetState();
}

class MainWidgetState extends State<MainWidget> {

    List<ItemData> _data = new List();
    Timer timer;

    Widget build(BuildContext context) {
        return new ListView(children: _data.map((item) => new ChildWidget(item)).toList());
    }

    @override
    void initState() {
        super.initState();
        timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
            ItemData data = await loadData();
            this.setState(() {
                _data = <ItemData>[data];
            });
        });
    }


    @override
    void dispose() {
        super.dispose();
        timer.cancel();
    }

    static int testCount = 0;

    Future<ItemData> loadData() async {
        testCount++;
        return new ItemData("Testing #$testCount");
    }
}

class ChildWidget extends StatefulWidget {

    ItemData _data;

    ChildWidget(ItemData data) {
        _data = data;
    }

    @override
    State<ChildWidget> createState() => new ChildState();
}

class ChildState extends State<ChildWidget> {

    @override
    Widget build(BuildContext context) {
        return new GestureDetector(onTap: () => foo(),
            child: new Padding(
                padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
                child: new Card(
                    child: new Container(
                        padding: const EdgeInsets.all(8.0),
                        child: new Text(widget._data.title),
                    ),
                ),
            )
        );
    }

    foo() {
        print("Card Tapped: " + widget._data.toString());
    }
}

class ItemData {
    final String title;

    ItemData(this.title);

    @override
    String toString() {
        return 'ItemData{title: $title}';
    }
}

[SOLVED] Flutter, This should sort your problem out. Basically you always want your Widgets created in your build method hierarchy. import 'dart:async'; import� Flutter - setState not updating inner Stateful Widget. 343. February 18, 2018, at 06:48 AM. Home Android Flutter - setState not updating inner Stateful Widget.

This was really giving me headache and no Google results were working. What finally worked was so simple. In your child build() assign the value to the local variable before you return. Once I did this everything worked with subsequent data loads. I even took out the initState() code.

Many thanks to @Simon. Your answer somehow inspired me to try this.

In your childState:

@override
Widget build(BuildContext context) {
_title = widget._title; // <<< ADDING THIS HERE IS THE FIX
return new GestureDetector(onTap: foo(),
   child: new Card(child: new Text(_title));

}

Hopefully this works in your code. For me, I use a Map for the entire JSON record passed in, rather than a single String, but that should still work.

setState method - State class - widgets library - Dart API, Calling setState notifies the framework that the internal state of this object has the user interface for this subtree might not be updated to reflect the new state. If I use a stateless widget than everything works as expected; when adding new items to the database, they are updated in the ListView. If I use a Stateful widget otherwise, the initial list is build but any further events are not displayed unless I manually scroll the list up/down. Why do I need a stateful widget for a ListView?

don't use a future within a future; use different function that will return each future individually like this

 List<Requests> requestsData;
 List<DocumentSnapshot> requestsDocumentData;
 var docId;



  @override
  void initState() {
    super.initState();

    getRequestDocs();
  }

  Future<FirebaseUser> getData() {
    var _auth = FirebaseAuth.instance;
    return _auth.currentUser();
  }

  getRequestDocs() {
    getData().then((FirebaseUser user) {
      this.setState(() {
        docId = user.uid;
      });
    });

    FireDb()
        .getDocuments("vendorsrequests")
        .then((List<DocumentSnapshot> documentSnapshots) {
      this.setState(() {
        requestsDocumentData = documentSnapshots;
      });
    });

    for (DocumentSnapshot request in requestsDocumentData) {
      this.setState(() {
        requestsData.add(Requests(
            request.documentID,
            request.data['requests'],
            Icons.data_usage,
            request.data['requests'][0],
            "location",
            "payMessage",
            "budget",
            "tokensRequired",
            "date"));
      });
    }
  }

you can create individual functions for

  FireDb().getDocuments("vendorsrequests")
            .then((List<DocumentSnapshot> documentSnapshots) {
          this.setState(() {
            requestsDocumentData = documentSnapshots;
          });
        });

and

  for (DocumentSnapshot request in requestsDocumentData) {
          this.setState(() {
            requestsData.add(Requests(
                request.documentID,
                request.data['requests'],
                Icons.data_usage,
                request.data['requests'][0],
                "location",
                "payMessage",
                "budget",
                "tokensRequired",
                "date"));
          });
        }

I found that the use of

this

with setState is must

setState is not updating the content!!! � Issue #20349 � flutter/flutter , I'm using Setstate but still one text is changing but the second is not. The text inside the list is not updating: interestList.add(new Container( child: class InterestPage extends StatefulWidget { @override _InterestPageState� How do you update the state of a sibling widget in Flutter? For example, if I have a rectangle widget, I can change its color from within the widget by calling setState() and changing the color variable (as the "Turn Green" button does below). But, say I wanted a button outside of the rectangle that would change its color.

Anyone know why is my widget not rerendering? : Flutter, Everything is working just fine except for this Text widget. For some reason, when I change the cardCounts in the setState() in the DragTarget it … class DeckCardsListView extends StatefulWidget { Function addCard; DeckCardsListView(this.addCard); @override Navigating Inside the Widget Tree. I am just wondering� The widget you want to show or hide must be the child of Visibility widget. data we assign the value inside a setState function to rebuild the widget and update. backgroundColor. To animate a button shrinking down to a circle, you just need to animate its width, from initial to 48 dp (initial height size).

Before, I used ListBuilder to generate a list of 70 numbers and it worked but it took a long time to generate the 70 numbers into custom widgets and also when I tapped a number just to change the

For relatively simple scenarios, where the application consists of a single screen, we could use Flutter’s Stateful widgets and call setState()to rebuild the widget after we’ve modified some

Comments
  • Please describe the various moving parts and provide example values for things that are expected to change. We need inputs and desired output.
  • I just added more information about the problem.
  • Have you tried to just wrap your _title = widget._title; in a setState?
  • @Robert Yes, I have to add that child Statefulwidget (the one with GestureRecognizer) works ok, the problem is trying to refresh the ancestor with new instances of childWidget
  • normally what I do is create a future and use Futurebuilder, that seems to do the job for me every time. You can do the same thing with Streams as well.
  • @JesúsMartín I forgot to mention if you have multiple list items of the same type then you should give each a Key. See flutter.io/widgets-intro/#keys for more info.