setState无法与Navigator.of(context)一起使用

时间:2020-01-12 21:06:02

标签: flutter state

我正在尝试颤抖Example app part 2。简而言之: 第一页:它建立了一个无限的单词列表,您可以在其中添加/删除一些您喜欢的单词 第二页列出了所有喜欢的单词。我们可以通过应用栏的actions: <Widget>[IconButton(icon: Icon(Icons.list), onPressed: _pushSaved)]访问第二页

enter image description here

我稍微修改了代码,因此第二页使用相同的列表生成器_buildWordsList,因此它们共享相同的布局/样式,我们也可以单击第二页上的单词以使其不受欢迎。

可悲的是,当我在第二页上单击一个喜欢的单词时,尽管它从所选单词中删除了它,但它仍然显示(因为它仍然很喜欢)

以下是“重要”代码(and here is a gist with all the code):

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}

class RandomWordsState extends State<RandomWords> {
  final List<WordPair> _suggestions = <WordPair>[];
  final List<WordPair> _saved = <WordPair>[]; // Add this line.
  # ...

  Widget _buildWordsList(WordPair itemAt(int index)) {
    return ListView.builder(
      ...
      itemBuilder: (BuildContext context, int i) {
        ...
        return _buildRow(item);
      },
    );
  }

  Widget _buildRow(WordPair pair) {

    return ListTile(
      title:  Text(pair),
      ...
      onTap: () {
        setState(() {
          if (alreadySaved) {
            _saved.remove(pair);
          } else {
            _saved.add(pair);
          }
        });
      },
    );
  }

  WordPair _suggestionsBuilder(int index) {
    // ... fill suggestions if needed, then return related index suggestion
    return _suggestions[index];
  }

  WordPair _savedGetter(int index) {
    // ... check if index exists, return null if not
    return _saved[index];
  }

  void _pushSaved() {
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) {
          return Scaffold(
              appBar: AppBar(
                title: Text("Favorites suggestions"),
              ),
              body: _buildWordsList(_savedGetter));
        },
      ),
    );
  }

  @override // Add from this line ...
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
        actions: <Widget>[
          IconButton(icon: Icon(Icons.list), onPressed: _pushSaved)
        ],
      ),
      body: _buildWordsList(_suggestionsBuilder),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}

在添加_pushSaved的{​​{1}}方法中,即使我将上下文传递到MaterialPageRoute时,当我在“已保存的建议”页面上并单击一个已保存的建议并触发行Navigator.of(context).push(,第二个列表不会重绘。但是我确定它会从onTaped单词列表中删除,因为当我回到“常规”列表时,它不再被选中(心脏不再红色)

因此状态已修改,但是页面在加载/推送后似乎未订阅更改。仅当我返回首页然后返回已保存的建议时,它才会更改。我该如何解决?

感谢您的阅读。我不知道在哪里寻求任何帮助。这种东西有不和谐/懈怠的地方吗?

1 个答案:

答案 0 :(得分:1)

这不是一个好的架构。 Navigazor.push()方法将小部件推入导航器堆栈中。由于您不会在任何地方弹出导航器堆栈,因此它们会堆积起来。您应该添加一个保存状态数据的全局变量,并仅使用setState更新ui。在此处查看更多信息:documentation