3

我正在使用这个reorderables包。这个包的工作原理是有一个子小部件列表,每个小部件都用Draggable包装并放在DragTarget中。在此之前 childs 键被分配给GlobalObjectKey
在创建 dragTarget 之后,它被分配(或重建?)到KeyedSubTree

dragTarget = KeyedSubtree(key: keyIndexGlobalKey, child: dragTarget);

根据包源代码中的注释,这应该在拖动时保留子小部件状态(toWrap):

// 我们将 toWrapWithGlobalKey 传递给 Draggable,这样当列表
项被拖动时,// 可访问性框架可以保留
拖动项的选中状态。
最终 GlobalObjectKey keyIndexGlobalKey = GlobalObjectKey(toWrap.key);

重新排序本身不是发生在 DragTarget 接受 Draggable 拖入其中的情况下,而是通过在每个子项周围使用 DragTarget 来获取 Draggable 悬停在当前位置的索引。当放开 Draggable 时,将调用一个重新排序函数,该函数从列表中删除(被拖动的)小部件并将其插入到新位置。

现在出现了我的问题:小部件的状态没有被保留。我做了一个简单的 TestWidget 来测试这个:

class TestWidget extends StatefulWidget{
  @override
  _TestWidgetState createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {

    Color boxColor;

    @override
    void initState() {
        super.initState();
        boxColor= Colors.blue;
    }

    @override
    Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
                decoration: BoxDecoration(color: boxColor),
                child: Text("Test"),
            ),
              FlatButton(
                  onPressed: (){
                    setState(() {
                        boxColor = Colors.red;
                    });
                  },
                  padding: EdgeInsets.all(8.0),
                  child: Text("Change to Red"),
                  color: Colors.grey,
              )
          ],
        );
    }
}

这个小部件有一个带有初始蓝色背景 (boxColor) 的容器和一个按钮。当按下按钮时,它会将 boxColor 更改为红色。开始拖动小部件的那一刻,它被重建并默认为初始状态(至少 Draggable 反馈是)。重新排序后不会更改并且小部件仍处于默认状态。

我的计划是列出不同的自定义小部件,用户可以在其中修改他们的内容,如果他们对订单不满意,他们可以拖动这些小部件并重新排列它们。

我的问题是:如何保留小部件的状态?

我正在考虑为每个带有所有状态相关变量的小部件创建一个类,并使用它来构建我的小部件,但这似乎非常臃肿,而且并不真正考虑到颤动。那不应该是StatefulWidget的状态的作用吗?

编辑:
所以我解决了我的问题,方法是使用ChangeNotifier为我的小部件状态创建一个额外的类,然后将我想要跟踪的所有变量移动到这个类中。所以我现在基本上有两个列表,一个用于可重新排序列表中的小部件,另一个用于它们的状态。我仍然认为这有点磨损。如果我的列表中的一个小部件有自己的其他子级,我需要为每个需要它的子级创建单独的状态类并将它们保存在某个地方。这会变得非常混乱,非常快。

4

0 回答 0