Flutter 颤振中利用子中心实现叠层子体的相对定位
我的布局的一部分显示了顶部有对象的图像。图像和对象位于Flutter 颤振中利用子中心实现叠层子体的相对定位,flutter,dart,Flutter,Dart,我的布局的一部分显示了顶部有对象的图像。图像和对象位于堆栈中。对于对象位置,我知道对象中心相对于图像的相对坐标。例如,(0,0)表示对象中心应位于图像的左上角,(0.23,0.7)表示“中心位于宽度的23%和高度的70%”。我知道对象的大小,但我不知道将分配给图像的大小 为此,我尝试使用Align,但它没有使用对象的中心:例如Align与Alignment(1,1)将对象的右下角点放在右下角。然后,我尝试添加一个变换来将对象的中心平移到(0,0),但这只适用于右下角,例如,当使用对齐(0,0)在
堆栈中
。对于对象位置,我知道对象中心相对于图像的相对坐标。例如,(0,0)表示对象中心应位于图像的左上角,(0.23,0.7)表示“中心位于宽度的23%和高度的70%”。我知道对象的大小,但我不知道将分配给图像的大小
为此,我尝试使用Align
,但它没有使用对象的中心:例如Align
与Alignment(1,1)
将对象的右下角点放在右下角。然后,我尝试添加一个变换来将对象的中心平移到(0,0),但这只适用于右下角,例如,当使用对齐(0,0)
在中心对齐时,位置错误
我曾想过使用定位
小部件,但我无法知道构建
函数中的图像大小
如何正确定位对象?在下面的示例中,如何使红色圆圈居中于绿色矩形的右下角?(以同样适用于其他坐标的方式)
类测试扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:世界其他地区(
儿童:[
扩大(
子:列(
儿童:[
扩大(
子:容器(
颜色:颜色,蓝色,
子:堆栈(
对齐:对齐.center,
儿童:[
AspectRatio(
方面:1.5,
子:容器(
颜色:颜色。绿色,
),
),
对齐(
对齐:对齐(1,
1) ,//应将圆心放在右下角
子:容器(
宽度:100,
身高:100,
//transform:Matrix4.translationValues(50,50,0),//除了右下角外不工作
装饰:盒子装饰(
颜色:颜色,红色,
形状:BoxShape.circle,
),
),
)
],
),
),
),
文本(“底部小部件”),
],
),
),
文本(“右小部件”),
],
),
);
}
}
这是一个基于pskink建议的定制多子女布局的解决方案:
enum _Slot {
image,
circle,
}
class MyDelegate extends MultiChildLayoutDelegate {
final FractionalOffset objectCenter;
MyDelegate({@required this.objectCenter});
@override
void performLayout(Size size) {
Size imageSize = Size.zero;
Offset imagePos = Offset.zero;
if (hasChild(_Slot.image)) {
imageSize = layoutChild(_Slot.image, BoxConstraints.loose(size));
// Center the image in the available space
imagePos = (size - imageSize as Offset) * 0.5;
positionChild(_Slot.image, imagePos);
}
if (hasChild(_Slot.circle)) {
Size childSize = layoutChild(_Slot.circle, BoxConstraints());
positionChild(
_Slot.circle,
imagePos +
objectCenter.alongSize(imageSize) -
childSize.center(Offset.zero));
}
}
@override
bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => false;
}
class Test extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(
child: Container(
color: Colors.blue,
child: Center(
child: CustomMultiChildLayout(
delegate:
MyDelegate(objectCenter: FractionalOffset(1, 1)),
children: [
LayoutId(
id: _Slot.image,
// Use AspectRatio to emulate an image
child: AspectRatio(
aspectRatio: 1.5,
child: Container(
color: Colors.green,
),
),
),
LayoutId(
id: _Slot.circle,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
)
],
),
),
),
),
Text('Bottom widget'),
],
),
),
Text('Right widget'),
],
),
);
}
}
enum\u插槽{
形象,,
圆圈
}
类MyDelegate扩展了MultiChildLayoutDelegate{
最终分数偏移对象中心;
MyDelegate({@required this.objectCenter});
@凌驾
空隙性能布局(尺寸){
Size imageSize=Size.zero;
偏移量imagePos=偏移量0;
if(hasChild(_Slot.image)){
imageSize=layoutChild(_Slot.image,BoxConstraints.loose(size));
//将图像置于可用空间的中心
imagePos=(大小-作为偏移的imageSize)*0.5;
positionChild(_Slot.image,imagePos);
}
if(hasChild(_槽圆)){
Size childSize=layoutChild(_Slot.circle,BoxConstraints());
体位儿童(
_槽圆,
imagePos+
objectCenter.alongSize(图像大小)-
childSize.center(偏移量为零);
}
}
@凌驾
bool shouldrellayout(MultiChildLayoutDelegate oldDelegate)=>false;
}
类测试扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:世界其他地区(
儿童:[
扩大(
子:列(
儿童:[
扩大(
子:容器(
颜色:颜色,蓝色,
儿童:中心(
孩子:自定义多孩子布局(
代表:
MyDelegate(对象中心:分数偏移(1,1)),
儿童:[
拉乌蒂德(
id:_Slot.image,
//使用AspectRatio模拟图像
孩子:AspectRatio(
方面:1.5,
子:容器(
颜色:颜色。绿色,
),
),
),
拉乌蒂德(
id:_Slot.circle,
子:容器(
宽度:100,
身高:100,
装饰:盒子装饰(
颜色:颜色,红色,
形状:BoxShape.circle,
),
),
)
],
),
),
),
),
文本(“底部小部件”),
],
),
),
文本(“右小部件”),
],
),
);
}
}
传递给代理的偏移可以是任何相对坐标。在上面的示例中,我通过(1,1),因此红色圆圈位于右下角的中心:
请详细说明您希望小部件的布局。添加您所需的图像也会有所帮助。尝试过自定义多儿童布局?@pskink感谢您的帮助!我会写信的
enum _Slot {
image,
circle,
}
class MyDelegate extends MultiChildLayoutDelegate {
final FractionalOffset objectCenter;
MyDelegate({@required this.objectCenter});
@override
void performLayout(Size size) {
Size imageSize = Size.zero;
Offset imagePos = Offset.zero;
if (hasChild(_Slot.image)) {
imageSize = layoutChild(_Slot.image, BoxConstraints.loose(size));
// Center the image in the available space
imagePos = (size - imageSize as Offset) * 0.5;
positionChild(_Slot.image, imagePos);
}
if (hasChild(_Slot.circle)) {
Size childSize = layoutChild(_Slot.circle, BoxConstraints());
positionChild(
_Slot.circle,
imagePos +
objectCenter.alongSize(imageSize) -
childSize.center(Offset.zero));
}
}
@override
bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => false;
}
class Test extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(
child: Container(
color: Colors.blue,
child: Center(
child: CustomMultiChildLayout(
delegate:
MyDelegate(objectCenter: FractionalOffset(1, 1)),
children: [
LayoutId(
id: _Slot.image,
// Use AspectRatio to emulate an image
child: AspectRatio(
aspectRatio: 1.5,
child: Container(
color: Colors.green,
),
),
),
LayoutId(
id: _Slot.circle,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
)
],
),
),
),
),
Text('Bottom widget'),
],
),
),
Text('Right widget'),
],
),
);
}
}