使用提供商和小吃店查找停用的小部件的祖先是不安全的

时间:2020-07-28 23:56:41

标签: flutter dart flutter-provider

我正在使用DismissibleWidget从列表中删除笔记。删除便笺后,会调用Snackbar,以使用户有机会撤消操作。单击按钮,然后将便笺重新插入列表中时,会出现此错误:

在处理手势时引发了以下断言: 查找停用的窗口小部件的祖先是不安全的。 此时,小部件的元素树的状态不再稳定。

  1. 可关闭的小部件

                 Dismissible(
                    direction: DismissDirection.endToStart,
                    onDismissed: (direction){
                      var removedNote = list.notes[index];
                      Provider.of<ListProvider>(context, listen: false).removeNote(index);
    
                      Scaffold.of(context).showSnackBar(
                          SnackBar(
                            content: Text("Nota removida"),
                            action: SnackBarAction(
                              label: "Desfazer",
                              onPressed: (){
                                Provider.of<ListProvider>(context, listen: false).insertNote(removedNote, index);
                              },
                            ),
                            duration: Duration(seconds: 3),
                          ),
                      );
                    },
    

    ...

  2. 提供程序中的方法

    void insertNote(NoteModel note, int index){
       notes.insert(index, note);
       fileRepository.saveToFile(notes);
       notifyListeners();
    

    }

1 个答案:

答案 0 :(得分:0)

我遇到了一些问题,但是使用BLoC作为状态管理,我的解决方案是从该小部件上方获取上下文。

出了什么问题?

您正在尝试寻找不再可用的上下文。这也是由于variable shadowing造成的。

解决方案?

到达该小部件上方的内容。

伪颤动码

class NameOfYourClass{
    build(BuildContext context1) {
      return ListView.builder(
          itemBuilder: (context2, index) {
             return MyItem(); 
          }
      );
    }
   }

假设您使用MyItem小部件关闭了Dismissiblecontext2将不再可用,如果您打印context2,它将看起来像这样( 注意:取消MyItem时:

SliverList(delegate: SliverChildBuilderDelegate#66afb(estimated child count: 1), renderObject: RenderSliverList#593ed relayoutBoundary=up2 DETACHED)

如您所见,该项目是树中的DETACHED。如果您打印context1,它将看起来像这样。

NameOfYourClass

因此,总而言之,不要这样做:

 Provider.of<ListProvider>(context2, listen: false).insertNote(removedNote, index);

执行此操作:

 Provider.of<ListProvider>(context1, listen: false).insertNote(removedNote, index);

请勿使用context1或context2,这只是出于说明目的。