我正在尝试使用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)
请使用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文章
| 归档时间: |
|
| 查看次数: |
517 次 |
| 最近记录: |