小部件不断重装

时间:2020-04-28 17:22:07

标签: flutter dart

请观看此36 seconds视频,以使其更加清晰,因为它解释起来太冗长:https://www.youtube.com/watch?v=W6WdQuLjrCs

我最好的猜测

  • 这是由于提供者。

应用程序结构->

Outer Page -> NoteList Page

外页代码:


class OuterPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return OuterPageState();
  }
}

class OuterPageState extends State<OuterPage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  int _selectedTab = 0;
  var noteList;
  final _pageOptions = [
    NoteList(),
    AnotherPageScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    var noteProvider = Provider.of<NotesProvider>(context, listen: false);
    var customFabButton;
    if (_selectedTab == 0) {
      customFabButton = FloatingActionButton(
        // Password section
        onPressed: () {
          navigateToDetail(context, Note('', '', 2), 'Add Note');
        },
        child: Icon(Icons.add),
      );
~~~ SNIP ~~~

“注释”标签,也称为NoteList页代码:

class NoteList extends StatefulWidget {
  NoteList();

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

class NoteListState extends State<NoteList> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  List<Note> noteList;
  int count = 0;

  @override
  Widget build(BuildContext context) {
    Provider.of<NotesProvider>(context).getNotes();
    return Scaffold(
        key: _scaffoldKey,
        body: Provider.of<NotesProvider>(context).count > 0
            ? NoteListScreen(_scaffoldKey)
            : CircularProgressIndicator());
  }
}

有关完整代码:请在此处检查:https://github.com/LuD1161/notes_app/tree/reusable_components

更新1-可能的解决方案是FutureBuilder

我知道FutureBuilder有可能的解决方案,但我认为甚至Provider也适用于此用例。

而且这里是反模式吗?

另外,请不要为同一件事建议另一个软件包,如果可能的话,请尝试将解决方案限制为Provider或基本库。

更新2-不适用于FutureBuilder

FutureBuilder在这里不能使用,因为delete中有一个list tile按钮,因此,当笔记被删除时,note list将不会得到更新。 / p>

1 个答案:

答案 0 :(得分:0)

问题是由于您正在从build方法调用的getNotes函数引起的。您正在从该函数调用notifyListeners。再次重新构建窗口小部件,并再次调用build方法,此循环继续。

您要么需要将provider的listen属性设置为false,但是这会破坏您的功能。要解决此问题,您必须将getNotes调用从构建函数移至initState,如下所示:

@override
void initState() {
  super.initState();
  postInit(() {
    Provider.of<NotesProvider>(context).getNotes();
  });
}

实现postInit(参考:Flutter Issue 29515):

extension StateExtension<T extends StatefulWidget> on State<T> {
  Stream waitForStateLoading() async* {
    while (!mounted) {
      yield false;
    }
    yield true;
  }

  Future<void> postInit(VoidCallback action) async {
    await for (var isLoaded in waitForStateLoading()) {}
    action();
  }
}

注意:除了编写postInit代码外,您还可以出于相同目的使用after_init包。

其他一些讨论类似问题的帖子: