Flutter 如何根据其子项定位复合TransformFollower';s码?
我正在使用Flutter 如何根据其子项定位复合TransformFollower';s码?,flutter,Flutter,我正在使用CompositedTransformTarget和CompositedTransformFollower显示一个OverlayEntry。如何相对于复合传输目标定位复合传输目标下方,即如何将其底部与目标顶部中心对齐,以便在目标上方水平居中显示,同时保持交互性(即对子对象进行命中测试应能正常工作) 我试图计算偏移量以提供给复合传输功率,但我无法进行正确的计算,因为当时我没有孩子的大小 示例代码: 导入“包装:颤振/材料.省道”; void main(){ runApp(MyApp())
CompositedTransformTarget
和CompositedTransformFollower
显示一个OverlayEntry
。如何相对于复合传输目标定位复合传输目标下方
,即如何将其底部与目标顶部中心对齐,以便在目标上方水平居中显示,同时保持交互性(即对子对象进行命中测试应能正常工作)
我试图计算偏移量
以提供给复合传输功率
,但我无法进行正确的计算,因为当时我没有孩子的大小
示例代码:
导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:主题数据(亮度:亮度。灯光),
家:脚手架(
appBar:appBar(标题:Text('test')),
主体:居中(子项:重叠按钮()),
),
);
}
}
类OverlayButton扩展StatefulWidget{
@凌驾
_OverlayButtonState createState()=>_OverlayButtonState();
}
类覆盖按钮状态扩展状态{
过度进入(OverlayEntry);;
最终层链接_LayerLink=LayerLink();
bool _=false;
@凌驾
无效处置(){
super.dispose();
如果(如图所示){
_hideOverlay();
}
}
void_showOverlay(){
如果(如图所示)返回;
_overlayEntry=_createOverlayEntry();
覆盖.of(上下文).insert(_overlayEntry);
_所示为真;
}
void _hideOverlay(){
_结果显示为假;
_覆盖入口。移除();
}
@凌驾
小部件构建(构建上下文){
返回复合传输目标(
链接:_layerLink,
子项:RaisedButton(子项:文本(‘打开覆盖’),按下时:_showOverlay),
);
}
OverlayEntry_createOverlayEntry(){
RenderBox RenderBox=context.findenderobject();
var anchorSize=renderBox.size;
返回覆盖入口(生成器:(上下文){
//TODO:动态使用正确的子项宽度/高度
//将我们正确定位在顶部+以锚为中心
var-childWidth=200.0;
var-childHeight=40.0;
变量childOffset=
偏移量(-(childWidth-anchorSize.width)/2,-(childHeight));
返回行(
儿童:[
复合传输功率(
链接:_layerLink,
偏移量:childOffset,
孩子:升起按钮(
子项:文本('close'),
按下按钮:_hideOverlay,
),
),
],
);
});
}
}
一般回答:
看起来我们想知道孩子的确切大小,然后再决定把孩子放在哪里。有一个用于此目的的小部件,名为CustomSingleChildLayout
。此外,如果需要布局多个子项,则应查看稍微复杂一点的版本,CustomMultiChildLayout
对于这种情况:
首先,您需要在正在构建的OverlayEntry
中插入一个CustomSingleChildLayout
,例如,我在这里添加了两行:
OverlayEntry _createOverlayEntry() {
RenderBox renderBox = context.findRenderObject();
var anchorSize = renderBox.size;
return OverlayEntry(builder: (context) {
return CompositedTransformFollower(
link: _layerLink,
child: CustomSingleChildLayout( // # Added Line 1 #
delegate: MyDelegate(anchorSize), // # Added Line 2 #
child: RaisedButton(
child: Text('close'),
onPressed: _hideOverlay,
),
),
);
});
}
然后,让我们创建一个处理业务逻辑的委托。请注意,我还创建了一个参数,用于接收“anchorSize”:
如您所见,在getPositionForChild
方法中,我们能够收集计算偏移量所需的所有信息。计算之后,我们可以返回该偏移量,CustomSingleChildLayout
将负责放置
为了扩展这个想法,你甚至可能不再需要复合传输follow
,你只需要做一个全屏覆盖,然后用这种方式计算偏移量。你必须用Follower小部件来实现这一点。我在这里做了一个
class MyDelegate extends SingleChildLayoutDelegate {
final Size anchorSize;
MyDelegate(this.anchorSize);
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
// we allow our child to be smaller than parent's constraint:
return constraints.loosen();
}
@override
Offset getPositionForChild(Size size, Size childSize) {
print("my size: $size");
print("childSize: $childSize");
print("anchor size being passed in: $anchorSize}");
// todo: where to position the child? perform calculation here:
return Offset(anchorSize.width, childSize.height / 2);
}
@override
bool shouldRelayout(_) => true;
}