如何更改MaterialPageRoute的状态?

时间:2019-10-29 12:39:10

标签: flutter dart

我正在遵循Flutter文档中的教程,您在其中创建了Startup命名应用程序。该应用程序包括两页:一页中有无限的随机生成的启动名称列表,您可以将它们添加到收藏夹中;另一页中的收藏夹页面中,您可以看到保存的名称。

完成本教程后,我尝试添加自己的一些功能,我希望能够通过在“收藏夹”页面上点击它来取消收藏名称。下面是将“收藏夹”页面推送到导航器的代码:

    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) {
          final Iterable<ListTile> tiles = _saved.map(
            (WordPair pair) {
              return ListTile(
                title: Text(
                  pair.asPascalCase, 
                  style: _biggerFont, 
                ),
                // Code I added // 
                trailing: Icon(Icons.delete), 
                onTap: () {
                  setState(() {
                    _saved.remove(pair);    
                  });
                },
                // End // 
              );
            },
          );
          final List<Widget> divided = ListTile
            .divideTiles(
              context: context,
              tiles: tiles,
            )
            .toList();

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

但是它并没有按预期的那样工作:您确实可以通过点击名称来保存名称,但是更改只会在您返回主页然后再次回到“收藏夹”页面(或在换句话说,何时调用Builder?)。

那我该如何解决呢?我是否需要为“收藏夹”页面创建一个有状态的小部件?如果是,如何将_saved集传递给新的小部件?

如果有人需要整个代码: https://pastebin.com/asLneaKe

1 个答案:

答案 0 :(得分:0)

使用StatefulBuilder包装可以正常工作。
您可以查看完整的代码和有效的演示

代码段

MaterialPageRoute<void>(
        builder: (BuildContext context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
            final Iterable<ListTile> tiles = _saved.map(

工作演示

enter image description here

完整代码

import 'package:english_words/english_words.dart' as prefix0;
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

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

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

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

class RandomWordsState extends State<RandomWords> {
  final List<WordPair> _suggestions = <WordPair>[];
  final Set<WordPair> _saved = Set<WordPair>();
  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Startup Name Generator'), actions: <Widget>[
        // Icone 3 linhas
        IconButton(
          icon: Icon(Icons.list),
          onPressed: _pushSaved,
        ),
      ]),
      body: _buildSuggestions(),
    );
  }

  Widget _buildRow(WordPair pair) {
    final bool alreadySaved = _saved.contains(pair);
    return ListTile(
        title: Text(
          pair.asPascalCase,
          style: _biggerFont,
        ),
        trailing: Icon(
          alreadySaved ? Icons.favorite : Icons.favorite_border,
          color: alreadySaved ? Colors.red : null,
        ),
        onTap: () {
          setState(() {
            if (alreadySaved) {
              _saved.remove(pair);
            } else {
              _saved.add(pair);
            }
          });
        });
  }

  Widget _buildSuggestions() {
    return ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: (context, i) {
        if (i.isOdd) return Divider();

        final index = i ~/ 2;
        if (index >= _suggestions.length) {
          _suggestions.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_suggestions[index]);
      },
    );
  }

  void _pushSaved() {
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
            final Iterable<ListTile> tiles = _saved.map(
              (WordPair pair) {
                return ListTile(
                  title: Text(
                    pair.asPascalCase,
                    style: _biggerFont,
                  ),
                  // Code I added //
                  trailing: Icon(Icons.delete),
                  onTap: () {
                    setState(() {
                      _saved.remove(pair);
                    });
                  },
                  // End //
                );
              },
            );
            final List<Widget> divided = ListTile.divideTiles(
              context: context,
              tiles: tiles,
            ).toList();

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