gpt4 book ai didi

flutter - 如何根据子项的大小定位 CompositedTransformFollower?

转载 作者:行者123 更新时间:2023-12-04 10:05:06 30 4
gpt4 key购买 nike

我正在使用 CompositedTransformTargetCompositedTransformFollower显示 OverlayEntry .如何定位 CompositedTransformFollower相对于 CompositedTransformTarget ,即如何将其底部与目标的顶部中心对齐,以便在目标上方水平居中显示它,同时保持交互性(即对 child 的 HitTest 应该有效)?

我试图计算 offsetCompositedTransformFollower ,但我无法正确计算,因为当时我没有 child 的大小。

示例代码:

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(brightness: Brightness.light),
home: Scaffold(
appBar: AppBar(title: Text('test')),
body: Center(child: OverlayButton()),
),
);
}
}

class OverlayButton extends StatefulWidget {
@override
_OverlayButtonState createState() => _OverlayButtonState();
}

class _OverlayButtonState extends State<OverlayButton> {
OverlayEntry _overlayEntry;
final LayerLink _layerLink = LayerLink();
bool _overlayIsShown = false;

@override
void dispose() {
super.dispose();
if (_overlayIsShown) {
_hideOverlay();
}
}

void _showOverlay() {
if (_overlayIsShown) return;
_overlayEntry = _createOverlayEntry();
Overlay.of(context).insert(_overlayEntry);
_overlayIsShown = true;
}

void _hideOverlay() {
_overlayIsShown = false;
_overlayEntry.remove();
}

@override
Widget build(BuildContext context) {
return CompositedTransformTarget(
link: _layerLink,
child: RaisedButton(child: Text('Open Overlay'), onPressed: _showOverlay),
);
}

OverlayEntry _createOverlayEntry() {
RenderBox renderBox = context.findRenderObject();
var anchorSize = renderBox.size;
return OverlayEntry(builder: (context) {
// TODO: dynamically use the correct child width / height for
// positioning us correctly on top + centered on the anchor
var childWidth = 200.0;
var childHeight = 40.0;
var childOffset =
Offset(-(childWidth - anchorSize.width) / 2, -(childHeight));
return Row(
children: <Widget>[
CompositedTransformFollower(
link: _layerLink,
offset: childOffset,
child: RaisedButton(
child: Text('close'),
onPressed: _hideOverlay,
),
),
],
);
});
}
}

最佳答案

一般回答:
看起来我们想知道 child 的确切大小,然后再决定将 child 放在哪里。为此目的制作了一个小部件,称为 CustomSingleChildLayout .此外,如果您需要布局多个子项,您应该查看稍微复杂一点的版本,CustomMultiChildLayout .
对于这种情况:
首先你需要插入一个 CustomSingleChildLayoutOverlayEntry例如,您正在构建,我在这里添加了 2 行:

  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,
),
),
);
});
}
然后让我们创建一个处理您的业务逻辑的委托(delegate)。请注意,我还创建了一个参数来接收您的“anchorSize”:
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;
}
如您所见,在 getPositionForChild方法,我们能够收集计算偏移量所需的所有信息。计算后,我们可以返回偏移量和 CustomSingleChildLayout会照顾安置。
要扩展这个想法,你可能甚至不需要 CompositedTransformFollower现在,您可以进行全屏叠加并以这种方式计算偏移量。

关于flutter - 如何根据子项的大小定位 CompositedTransformFollower?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61623034/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com