Flutter - setState not updating inner Stateful Widget

后端 未结 5 467
生来不讨喜
生来不讨喜 2021-02-01 02:57

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

5条回答
  •  天涯浪人
    2021-02-01 03:28

    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 {
    
        List _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 = [data];
                });
            });
        }
    
    
        @override
        void dispose() {
            super.dispose();
            timer.cancel();
        }
    
        static int testCount = 0;
    
        Future loadData() async {
            testCount++;
            return new ItemData("Testing #$testCount");
        }
    }
    
    class ChildWidget extends StatefulWidget {
    
        ItemData _data;
    
        ChildWidget(ItemData data) {
            _data = data;
        }
    
        @override
        State createState() => new ChildState();
    }
    
    class ChildState extends State {
    
        @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}';
        }
    }
    

提交回复
热议问题