2017-08-22 110 views
0

我一直在面对一些与setState函数有关的问题,同时使用有状态的小部件在定时器的帮助下更新自己。下面的代码显示了2个主要的类,它们复制了我如何发现这个错误。文本小部件“Lorem”应该在10秒内插入 - 它是 - 但它从未显示。我试图调试数组“Items”,它在012秒后会在5秒后包含“lorem”文本小部件,因为它应该如此。 “构建”功能可以运行,但在界面上没有任何区别。setState不会更新用户界面

class textList extends StatefulWidget { 

    @override 
    State<StatefulWidget> createState() => 
     new _textListState(); 
} 

class _textListState extends State<textList> 
    with TickerProviderStateMixin { 

    List<Widget> items = new List(); 
    Widget lorem = new textClass("Lorem"); 
    Timer timer; 

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

    items.add(new textClass("test")); 
    items.add(new textClass("test")); 

    timer = new Timer.periodic(new Duration(seconds: 5), (Timer timer) { 
     setState(() { 
     items.removeAt(0); 
     items.add(lorem); 
     }); 
    }); 
    } 

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

    @override 
    Widget build(BuildContext context) { 
    Iterable<Widget> content = ListTile.divideTiles(
     context: context, tiles: items).toList(); 

    return new Column(
     children: content, 
    ); 
    } 
} 

class textClass extends StatefulWidget { 
    textClass(this.word); 

    final String word; 

    @override 
    State<StatefulWidget> createState() => 
     new _textClass(word); 
} 

class _textClass extends State<textClass> 
    with TickerProviderStateMixin { 
    _textClass(this.word); 

    String word; 
    Timer timer; 

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

    timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) { 
     setState(() { 
     word += "t"; 
     }); 
    }); 
    } 

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


    @override 
    Widget build(BuildContext context) { 
    return new Text(word); 
    } 
} 

这不是我怎么来找到这个错误,但这个是复制它的最简单方法。主要思想是:孩子们的文本应该不断更新自己(在这种情况下,最后加上“t”),5秒后,最后一个应该替换为Text Widget“Lorem”,会发生什么在列表中但不在UI中。

回答

1

这里的什么是错的:

  • 一个State不应该有任何构造函数的参数。使用widget属性可以访问关联的StatefulWidget的最终属性。
  • 颤振正在重用您的_textClass实例,因为类名称和键匹配。这是一个问题,因为您只在initState中设置了widget.word,因此您没有获取新的word配置信息。您可以通过给StatefulWidget实例指定唯一的密钥来消除它们的歧义并解决旧的State问题,或者您可以保留旧的State并实现didUpdateWidget。后一种方法如下所示。

video

import 'dart:async'; 
import 'package:flutter/material.dart'; 

void main() { 
    runApp(new MaterialApp(
    home: new Scaffold(
     appBar: new AppBar(title: new Text('Example App')), 
     body: new textList(), 
    ), 
)); 
} 

class textList extends StatefulWidget { 

    @override 
    State<StatefulWidget> createState() => 
     new _textListState(); 
} 

class _textListState extends State<textList> 
    with TickerProviderStateMixin { 

    List<Widget> items = new List(); 
    Widget lorem = new textClass("Lorem"); 
    Timer timer; 

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

    items.add(new textClass("test")); 
    items.add(new textClass("test")); 

    timer = new Timer.periodic(new Duration(seconds: 5), (Timer timer) { 
     setState(() { 
     items.removeAt(0); 
     items.add(lorem); 
     }); 
    }); 
    } 

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

    @override 
    Widget build(BuildContext context) { 
    Iterable<Widget> content = ListTile.divideTiles(
     context: context, tiles: items).toList(); 

    return new Column(
     children: content, 
    ); 
    } 
} 

class textClass extends StatefulWidget { 
    textClass(this.word); 

    final String word; 

    @override 
    State<StatefulWidget> createState() => 
     new _textClass(); 
} 

class _textClass extends State<textClass> 
    with TickerProviderStateMixin { 
    _textClass(); 

    String word; 
    Timer timer; 

    @override 
    void didUpdateWidget(textClass oldWidget) { 
    if (oldWidget.word != widget.word) { 
     word = widget.word; 
    } 
    super.didUpdateWidget(oldWidget); 
    } 

    @override 
    void initState() { 
    super.initState(); 
    word = widget.word; 

    timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) { 
     setState(() { 
     word += "t"; 
     }); 
    }); 
    } 

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


    @override 
    Widget build(BuildContext context) { 
    return new Text(word); 
    } 
}