2017-08-22 23 views
0

ステートフルウィジェットを使用しているときに、私はがタイマーの助けを借りてを更新するというsetState関数に関するいくつかの問題に直面しています。下のコードは、このエラーを見つけ出す方法を再現する2つの主要なクラスを示しています。テキストウィジェット「Lorem」は10秒以内に挿入する必要がありますが、それは表示されません。私は配列 "アイテム"をデバッグしようとしました。は、 "lorem"テキストウィジェットを5秒後に含めるとに含まれています。 "ビルド"機能は動作しますが、UIには何の違いもありません。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秒後にテキストウィジェット「Lorem」の最後のテキストを置き換える必要がありますリストには表示されますが、UIには表示されません。

答えて

1

はここで間違っているものです:

  • Stateは、任意のコンストラクタの引数を持つべきではありません。 widgetプロパティを使用して、関連付けられたStatefulWidgetの最終プロパティにアクセスします。
  • フラッターは、クラス名とキーが一致するため、_textClassインスタンスを再利用しています。新しいword構成情報が表示されないように、widget.wordinitStateに設定するだけで問題になります。これを修正するには、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); 
    } 
} 
関連する問題