强制堆栈重新创建自定义小部件

时间:2019-02-04 16:43:23

标签: dart flutter bloc

我有一堆两个自定义的小部件,它们都位于:

  1. 个人资料卡
  2. ProfileCardDummy

ProfileCard :此自定义的有状态小部件是第一个堆栈的堆栈,顶部是堆栈。此小部件无法使用。

ProfileCardDummy :此自定义的无状态小部件是堆栈的背景小部件。

所以 ProfileCard 小部件是堆栈顶部的一个,其他背景堆栈是 ProfileCardDummy

我的代码是这样的:

return Stack(
    alignment: AlignmentDirectional.center,
    children:
    state.profileCards.map((ProfileCardModel card) {

        backCardWidth += 10.0;
        backBottom -= decrementalBottom;

        if (state.profileCards.indexOf(card) ==
            state.profileCards.length - 1) {
            return BlocProvider < ProfileCardBloc > (
                bloc: _profileCardBloc,
                child: ProfileCard(
                    isBack: 0,
                    bottom: initialBottom,
                    cardModel: card,
                    rotation: 0.0,
                    skew: 0.0,
                    img: image1,
                    addCard: () {},
                    onPressed: () {},
                ),
            );
        } else {
            return ProfileCardDummy(
                card,
                image2,
                backBottom,
                backCardWidth,
            );
        }
    }).toList()
);

所有的魔术都发生在 ProfileCard 中,在那里我使用BloC模式获取卡的内容(主要是按钮)。

我在ProfileCard状态的构造函数上调度bloc事件。像这样:

class _ProfileCardState extends State<ProfileCard> {
  final VoteButtonBloc _voteButtonBloc = VoteButtonBloc();


  _ProfileCardState(){
    print("Dispatching ${widget.cardModel}");
    _voteButtonBloc.dispatch(FetchButtons(widget.cardModel));
  }
...
...

问题是,当我运行代码时,第一个ProfileCard正确显示其按钮。现在,当我关闭它时,将显示第二个ProfileCard,但带有第一个ProfileCard的按钮(我已将其关闭)。

经过数小时的调试,我注意到ProfileCard( _ProfileCardState())的构造函数仅在第一个卡上被调用。其他卡片是继承头等舱的按钮。

在Stack文档中,它说:

If you reorder the children in this way, consider giving the children non-null keys.
These keys will cause the framework to move the underlying objects for the children to their new locations rather than recreate them at their new location.

我的ProfileCard以键作为参数(因为它扩展了StatefulWidget),但是我没有传递任何键。传递密钥可以解决这个问题?如何传递唯一密钥?:P

是否有一种方法可以强制重新创建小部件以强制再次调用构造函数,从而正确获取按钮?

1 个答案:

答案 0 :(得分:1)

第一件事。当列表中有相同的小部件时,Flutter不会知道它们是否更改了顺序,这就是key可以为您提供帮助的地方。

要查看如何使用键,您可能需要检查here,而该video很好地解释了要重新订购商品的列表情况。

在树中已经存在的窗口小部件状态中,setState会调用build,但不会调用构造函数或initState,只有在实际插入窗口小部件时才调用它们。在树上。当父控件发生更改时,Flutter会在其子控件上寻找更改,并在每个小部件状态上调用didUpdateWidget方法,您可以在其中覆盖并实际比较旧控件和新控件的更改。

由于您一直想重建小部件,因此只需给它一个UniqueKey

ProfileCard(key: UniqueKey());

这将告诉Flutter,您实际上是在创建一个新对象,而不是重新使用旧对象。