Flutter基础之Stack与Positioned
Stack一般与Positioned配合使用,在Flutter中我们称之为层叠布局,顾名思义,它允许子Widget按照代码顺序堆叠起来。并可以利用其相关属性调整其子Widget的位置。
- Stack和Positioned
Container (
width: 300,
height: 300,
color: Colors.red,
child: Stack(
children: [
Positioned(child: Text("居左"), left: 15,),
Positioned(child: Text("顶部居左"), left: 15, bottom: 15,),
Positioned(child: Text("顶部居右"), right: 15, top: 15,),
Positioned(child: Text("底部居右"), right: 15, bottom: 15,),
],
),
);
运行效果:
解释:在一个长宽为300的正方形Container中,有四个Positioned。我们发现第一个Positioned没有设置顶部间距,便默认顶部对齐。其它三个子Widget通过设置Positioned的上下左右距离,使之可以在父Widget上面进行绝对定位。那怎样修改默认对齐方式呢?我们接着往下看。
- alignment属性
在Stack中我们可以通过alignment属性来修改默认对齐方式。但是alignment也会影响没有被Positioned包起来的Widget。如下代码:
Container (
width: 300,
height: 300,
color: Colors.red,
child: Stack(
//未被Positioned包括或没有设置位置的Widget对齐方式
alignment: Alignment.center,
children: [
Text("没有Positioned"),
Positioned(child: Text("居中")),
Positioned(child: Text("居左"), left: 15,),
Positioned(child: Text("底部居左"), left: 15, bottom: 15,),
Positioned(child: Text("顶部居右"), right: 15, top: 15,),
Positioned(child: Text("底部居右"), right: 15, bottom: 15,),
],
),
);
运行效果:
我们设置了alignment值为 Alignment.center。那么第一个居左的Text,现在在垂直方向上居中了。没有设置上下左右间距的Widget没有被Positioned包括的Text与也相对于父Widget居中了。
结论:可以通过设置alignment来确定未指定位置信息的元素的对齐方式。以下为alignment支持的值:
/// The top left corner.
static const Alignment topLeft = Alignment(-1.0, -1.0);
/// The center point along the top edge.
static const Alignment topCenter = Alignment(0.0, -1.0);
/// The top right corner.
static const Alignment topRight = Alignment(1.0, -1.0);
/// The center point along the left edge.
static const Alignment centerLeft = Alignment(-1.0, 0.0);
/// The center point, both horizontally and vertically.
static const Alignment center = Alignment(0.0, 0.0);
/// The center point along the right edge.
static const Alignment centerRight = Alignment(1.0, 0.0);
/// The bottom left corner.
static const Alignment bottomLeft = Alignment(-1.0, 1.0);
/// The center point along the bottom edge.
static const Alignment bottomCenter = Alignment(0.0, 1.0);
/// The bottom right corner.
static const Alignment bottomRight = Alignment(1.0, 1.0);
注:设置alignment属性也可以通过Alignment或FractionalOffset的x、y值来设置。x、y的值参考以上代码。
下一篇文章在讲述Align组件时,将会讲一下Alignment和FractionalOffset的x、y值所代表的具体含义。
- fit属性
在Stack中还有另外一个属性fit,我们可以通过fit属性来设置未指定位置的子Widget的空间大小。
fit有三个值可选:
enum StackFit {
//使用子Widget 自身的大小
loose,
//使子widget与stack大小一致
expand,
//stack的父widget的布局大小约束无修改的传递给 Stack 的子Widget
passthrough,
}
我们来看一下loose:
Container(
width: 300,
height: 300,
color: Colors.red,
child: Stack(
fit: StackFit.loose,
children: [
Container(
width: 200,
height: 20,
color: Colors.orange,
child: Text("没有Positioned")
),
Positioned(child: Text("底部居左"), left: 15, bottom: 15,),
],
),
);
运行效果:
我们发现设置fit: StackFit.loose后橘色区域与设置的宽高一致,我们看设置fit: StackFit.expand的效果:
说明fit属性为 StackFit.expand时,没有设置定位的子widget会占满stack。
passthrough官方文档说明的是将stack的父widget的布局大小约束无修改的传递给 Stack 的子Widget。试过之后发现与expand效果一致,也许还有其它区别剑老师尚未发现。
- overflow
接下来我们看一下overflow属性,overflow比较简单,有两个值:
enum Overflow {
/// Overflowing children will be visible.
///
/// The visible overflow area will not accept hit testing.
visible,
/// Overflowing children will be clipped to the bounds of their parent.
clip,
}
overflow属性值为Overflow.clip时,Stack的子widget超出部分会被剪裁,值为Overflow.visible 时则不会被裁剪。代码如下:
Container(
width: 300,
height: 300,
color: Colors.red,
child: Stack(
overflow: Overflow.visible,
children: [
Positioned(child: Text("ddddddddddddddddddd"), left: 250, bottom: 15,),
],
),
);
运行效果:
当overflow值为Overflow.clip时运行效果
本文首发于公众号“App程序猿”
原本地址:
发布于 2021-03-29 20:04