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(),
),
),
],
);
}),
),
);
}
}
解决方案
更新
请使用LayoutBuilder
来构建Draggable
. 它的 builder 函数接收一个约束参数,您可以使用它来调整反馈的大小。这要好得多,因为GlobalKey
如果你有一个包含动态数据的列表,你就不能总是拥有一个。
例子:
LayoutBuilder(
builder: (context, constraints) => Draggable(
child: Container(...),
feedback: Container (
width: constraints.maxWidth,
)
),
);
初始职位
您可以通过使用其 GlobalKey 来确定 Widget 的大小。我在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,
),
);
}
}
你也可以看看这篇 Medium 文章
推荐阅读
- java - 如何在基于 Debian Java 的 Docker 映像中减少 python 的大小?
- c++ - C ++ std中的条件变量与互斥锁
- matlab - 将向量输入传递给 MATLAB 函数
- r - R匹配/比较R中的两个矩阵,但循环似乎效果不佳
- javascript - Chrome 自定义选项卡获取内容和页面事件监听器
- vuejs2 - Nuxt.js 未知商店
- php - Vue.js 没有正确更新 URL
- c - 如何在 C 中使常量仅对特定源文件可见?
- javascript - 如何同步范围类型
- docker - 如何使用 iptables 允许 docker 使用特定端口 --> dport 在容器内使用端口