Flutter:在GridView.custom中获取Draggable组件约束的方法
解决Draggable feedback尺寸匹配GridView子组件的问题
要让Draggable的feedback尺寸和当前GridView子组件一致,你可以用LayoutBuilder包裹LongPressDraggable,它能在构建时获取到父组件(也就是GridView子项)的约束,直接用这些约束来设置SizedBox的宽高。
核心思路
SliverChildBuilderDelegate虽然不直接提供constraints参数,但LayoutBuilder会将父级传递来的约束(即GridView子项的实际尺寸限制)暴露给builder函数,我们可以直接用这个约束的maxWidth和maxHeight作为feedback的宽高,确保反馈组件和原组件尺寸完全一致。
修改后的完整代码
return GridView.custom( shrinkWrap: true, primary: false, scrollDirection: Axis.vertical, controller: _scrollController, physics: const ClampingScrollPhysics(), gridDelegate: SliverQuiltedGridDelegate( crossAxisCount: 4, mainAxisSpacing: 10, crossAxisSpacing: 10, repeatPattern: QuiltedGridRepeatPattern.inverted, pattern: widget.pattern, ), childrenDelegate: SliverChildBuilderDelegate( childCount: widget.children.length, (context, index) { var selectedWidget = widget.children[index]; // 用LayoutBuilder获取子组件的约束 return LayoutBuilder( builder: (context, constraints) { return LongPressDraggable<GlobalKey>( data: selectedWidget.key, onDragStarted: _onDragStarted, onDragEnd: _onDragEnd, feedback: SizedBox( width: constraints.maxWidth, height: constraints.maxHeight, child: selectedWidget, ), childWhenDragging: Container(), child: selectedWidget, ); }, ); }, ), );
备选方案(通过GlobalKey获取尺寸)
如果因为场景限制无法使用LayoutBuilder,也可以给子组件绑定GlobalKey,在拖拽开始时获取它的渲染尺寸:
- 确保每个
selectedWidget已绑定GlobalKey - 在
_onDragStarted中获取并保存尺寸:
Size? _draggedItemSize; void _onDragStarted() { final renderBox = (selectedWidget.key as GlobalKey).currentContext?.findRenderObject() as RenderBox?; if (renderBox != null) { _draggedItemSize = renderBox.size; } }
- 在feedback的SizedBox中使用
_draggedItemSize?.width和_draggedItemSize?.height
不过这种方法需要等待组件渲染完成后才能获取尺寸,不如LayoutBuilder在构建阶段直接获取约束来得可靠,优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者KosherHotDog
相关产品推荐
相关产品推荐

