setState是否无法在Dart / Flutter中重新加载状态?

时间:2018-12-19 05:46:58

标签: dart flutter sharedpreferences

我遵循了Google CodeLabs的Flutter教程-

Part 1

Part 2

然后我尝试添加SharedPreferences来保留数据。保存数据效果很好,但是删除却不能。

我的完整代码位于https://github.com/deadcoder0904/flutter-startup-name-generator/

屏幕1(列出所有启动名称)

flutter_heart

屏幕2(此处显示了屏幕1中所有保存的启动名称)

flutter_trash

Screen 2上,通过单击垃圾桶图标删除启动名称不会立即删除数据。我必须横穿Screen 1并再次回到Screen 2才能看到该项目已被删除。

该错误位于下面的setState中,或者您也可以on Github以良好的格式查看该错误

void _pushSaved() {
    Navigator.of(context).push(
        MaterialPageRoute<void>(
            builder: (BuildContext context) {
                final Iterable<ListTile> tiles = _saved.map(
                    (String word) {
                        return ListTile(
                            title: Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: <Widget>[
                                    Text(
                                        word,
                                        style: _biggerFont,
                                    ),
                                    IconButton(
                                        icon: const Icon(Icons.delete),
                                        onPressed: () {
                                            setState(() {
                                                _saved.remove(word);
                                                savePrefs(_saved);
                                            });
                                        },
                                    )
                                ],
                            ),
                        );
                    },
                );

                final List<Widget> divided = ListTile.divideTiles(
                    context: context,
                    tiles: tiles,
                ).toList();

                return Scaffold(
                    appBar: AppBar(
                        title: const Text('Saved Suggestions'),
                    ),
                    body: ListView(children: divided),
                );
            },
        ),
    );
}
_saved.remove(word);中的

setState不会立即删除启动名称。

我应该制作另一个有状态组件吗?我该如何解决?

1 个答案:

答案 0 :(得分:1)

那是因为您在builder内部创建的窗口小部件不是Stateful

创建一个StatefulWidget,然后从MaterialPageRoute调用它。

只需几处更改:

void _pushSaved() {
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) => FavoriteList(
            data: _saved, savePrefs: savePrefs, biggerFont: _biggerFont),
      ),
    );
  }

创建一个新的StatefulWidget

class FavoriteList extends StatefulWidget {
  final Set<String> data;
  final Function savePrefs;
  final TextStyle biggerFont;
  FavoriteList({Key key, this.data, this.savePrefs, this.biggerFont})
      : super(key: key);

  @override
  _FavoriteListState createState() => _FavoriteListState();
}

class _FavoriteListState extends State<FavoriteList> {
  Set<String> _saved;
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  @override
  void initState() {
    _saved = widget.data;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final Iterable<ListTile> tiles = _saved.map(
      (String word) {
        return ListTile(
          title: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(
                word,
                style: widget.biggerFont,
              ),
              IconButton(
                icon: const Icon(Icons.delete),
                onPressed: () {
                  setState(() {
                    _saved.remove(word);
                    widget.savePrefs(_saved);
                  });
                },
              )
            ],
          ),
        );
      },
    );

    final List<Widget> divided = ListTile.divideTiles(
      context: context,
      tiles: tiles,
    ).toList();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Saved Suggestions'),
      ),
      body: ListView(children: divided),
    );
  }
}