Flutter - setState 不更新内部有状态小部件

新手上路,请多包涵

基本上我正在尝试制作一个应用程序,其内容将使用从网站获取信息的异步功能进行更新,但是当我尝试设置新状态时,它不会重新加载新内容。如果我调试应用程序,它会显示当前内容是新内容,但在“重建”整个小部件后,它不会显示新信息。

编辑:loadData() 方法,基本上是用http 包读取一个URL,该URL 包含一个JSON 文件,其内容每5 分钟更新一次,有新消息。例如,带有体育实时记分牌的 .json 文件,其分数总是在变化,因此内容应该总是随着新结果而变化。

 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;
  }
}

原文由 Jesús Martín 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

这应该可以解决您的问题。基本上,您总是希望在您的 build 方法层次结构中创建小部件。

 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}';
    }
}

原文由 Simon 发布,翻译遵循 CC BY-SA 3.0 许可协议

就我而言,它只是 将状态定义为类属性,而不是构建方法中的局部变量

这样做 -

   List<Task> tasks = [
    Task('Buy milk'),
    Task('Buy eggs'),
    Task('Buy bread'),
  ];
  @override
  Widget build(BuildContext context) {

    return ListView.builder(
      itemBuilder: (context, index) => TaskTile(
...

而不是这个 -

  @override
  Widget build(BuildContext context) {
  List<Task> tasks = [
    Task('Buy milk'),
    Task('Buy eggs'),
    Task('Buy bread'),
  ];

    return ListView.builder(
      itemBuilder: (context, index) => TaskTile(
...

原文由 Piyush 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题