与孩子大小相同的可拖动反馈

use*_*787 5 flutter

我正在尝试使用Draggable小部件实现可刷卡(类似于 Tinder 应用程序)。刷卡工作正常,只是我正在努力弄清楚如何将Draggable'sfeedback的大小设置为与child. 问题是包含项目的Stack小部件Draggable具有取决于屏幕尺寸的动态尺寸,因此无法将尺寸设置为固定值。

我试图使用 LayoutBuilder,希望我能够使用RenderBox box = context.findRenderObject() as RenderBox;以下异常获得大小RenderBox was not laid out。阅读文档后,发现无法在build函数中调用获取RenderBox 。

另一种选择可能是使用MediaQuery.of(context).size,但这并不方便,因为它仅返回呈现应用程序的窗口大小(整个屏幕)。

如果有人能给我一个如何做到这一点的线索,我将不胜感激。

代码

class CardStack extends StatefulWidget {
  @override
  _CardStackState createState() => new _CardStackState();
}

class _CardStackState extends State<StatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return new Container(
      padding: EdgeInsets.all(32),
      child: SizedBox.expand(
        child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
          RenderBox box = context.findRenderObject() as RenderBox;
          return new Stack(
            children: <Widget>[
              new Draggable(
                key: ObjectKey('card1'),
                child: new Card(
                  color: Colors.red,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  child: Container(
                  ),
                ),
                feedback: new Card(
                  color: Colors.red,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  child: Container(
                    width: box.size.width, // TODO: how to get same size as child??
                    height: box.size.height, // TODO: how to get same size as child??
                  ),
                ),
                childWhenDragging: Container(),
              ),
              new Draggable(
                key: ObjectKey('card2'),
                child: new Card(
                  color: Colors.green,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  child: Container(
                  ),
                ),
                feedback: new Card(
                  color: Colors.green,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  child: Container(
                    width: box.size.width,
                    height: box.size.height,
                  ),
                ),
                childWhenDragging: Container(),
              ),
              new Listener(
                onPointerDown: (PointerDownEvent event) {
                  print(event.position);
                },
                child: new Draggable(
                  key: ObjectKey('card3'),
                  child: new Card(
                    color: Colors.blue,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10)),
                    child: Container(
                    ),
                  ),
                  feedback: new Card(
                    color: Colors.blue,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10)),
                    child: Container(
                      width: box.size.width,
                      height: box.size.height,
                    ),
                  ),
                  childWhenDragging: Container(),
                ),
              ),
            ],
          );
        }),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Jan*_*ies 9

更新

请使用LayoutBuilder来构建Draggable. 它的构建器函数接收一个约束参数,您可以使用该参数调整反馈的大小。这要好得多,因为GlobalKey如果您有一个包含动态数据的列表,则您不能总是拥有一个。

例子:

LayoutBuilder(
  builder: (context, constraints) => Draggable(
    child: Container(...),
    feedback: Container (
      width: constraints.maxWidth,
    )
  ),
);
Run Code Online (Sandbox Code Playgroud)

初始帖子

您可以使用 Widget 的 GlobalKey 来确定其大小。我在GitHub上针对 ListView发布了此评论,但我认为您将能够对 Stack 使用相同的示例。

ListView.builder(
  itemCount: 25,
  itemBuilder: (BuildContext context, int index) {
    GlobalKey myKey = GlobalKey();
    return Draggable(
      child: ListTile(
        key: myKey,
          title: Text("Tile #$index"),
        ),
        childWhenDragging: Opacity(
          opacity: 0.2,
          child: ListTile(
            title: Text("Tile #$index"),
          ),
        ),
        feedback: FeedbackWidget(
          dragChildKey: myKey,
          child: ListTile(
            title: Text("Tile #$index"),
          ),
       ),
     );
  }
)


class FeedbackWidget extends StatelessWidget{
  final GlobalKey dragChildKey;
  final Widget child;
  const FeedbackWidget({Key key, this.dragChildKey, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //Determine the size of the original widget
    final RenderBox renderBoxRed = dragChildKey.currentContext.findRenderObject();
    final size = renderBoxRed.size;
    return Container(
      width: size.width,
      height: size.height,
      child: Material(
        child: child,
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

你也可以看看这篇Medium文章