1. 基本介绍
Stack、Row、Column 是 Flutter 中最常用的布局组件了,其实在很多别的语言中,也是这三种布局最为常用。但是作为区别,Row、Column 是最通用的 Flex 布局的思想,而 Stack 可以更多的理解为绝对布局组件,可以指定上下左右的约束这种。
Row、和 Column 很早之前就写过了,想了解的可以看这里 -> Flutter入门(8):Flutter 组件之 Row、Column 详解
2. 示例代码
代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。
3. 属性介绍
属性 | 介绍 |
---|---|
alignment | 对齐方式,作用于没有设置约束的子控件。默认为 AlignmentDirectional.topStart |
textDirection | 布局方向,作用于没有设置约束的子控件。默认为 TextDirection.ltr 从左往右布局,TextDirection.rtl 从右往左布局,会覆盖 alignment 的设置 |
fit | 没有设置约束的子控件的填充方式,默认为 StackFit.loose |
overflow | 子控件边缘超出 Stack 边缘的部分是否裁剪,默认为 Overflow.clip |
clipBehavior | 边缘超出子控件部分裁剪方式,默认为 Clip.hardEdge |
4. 详解
Stack 相较于 Row 和 Column,他可以使用 Positioned 组件,这个组件可以设置,上下左右以及宽高的约束,完成绝对布局。
4.1 示例代码
import 'package:flutter/material.dart';
class FMStackVC extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Stack'),
),
body: Container(
width: 400,
height: 600,
color: Colors.grey,
child: _stack(),
),
);
}
Stack _stack(){
return Stack(
// alignment: Alignment.topRight,
// clipBehavior: Clip.none,
// textDirection: TextDirection.rtl,
// overflow: Overflow.visible,
// fit: StackFit.loose,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
ConstrainedBox(
constraints: BoxConstraints(),
child: Text("一行文字", style: TextStyle(backgroundColor: Colors.yellow),),
),
_positionedForAll(),
_positionedForLeftTop(),
_positionedForClip(),
],
);
}
// 四边约束,指定4个边的距离,然后这个 Positioned 会被拉伸,直到边距和设定一致
Positioned _positionedForAll(){
return Positioned(
left: 150,
top: 150,
bottom: 10,
right: 10,
child: Container(
color: Colors.cyan,
),
);
}
// 位置约束,指定两边位置,设置过大小的 Container 就是绝对定位了
Positioned _positionedForLeftTop(){
return Positioned(
left: 30,
top: 30,
child: Container(
width: 200,
height: 200,
color: Colors.yellow,
),
);
}
// 超出父控件边界的约束
Positioned _positionedForClip(){
return Positioned(
left: 30,
top: 500,
child: Container(
width: 200,
height: 200,
color: Colors.lightGreenAccent,
alignment: Alignment.bottomCenter,
child: FlatButton(
onPressed: (){
print("Button Clicked");
},
child: Text("Button"),
),
),
);
}
}
Stack normal.png
4.2 alignment 对齐方式
使用 alignment 对齐方式,来对没有位置约束的子组件进行约束。
Stack _stack(){
return Stack(
alignment: Alignment.topRight,
// clipBehavior: Clip.none,
// textDirection: TextDirection.rtl,
// overflow: Overflow.visible,
// fit: StackFit.loose,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
ConstrainedBox(
constraints: BoxConstraints(),
child: Text("一行文字", style: TextStyle(backgroundColor: Colors.yellow),),
),
_positionedForAll(),
_positionedForLeftTop(),
_positionedForClip(),
],
);
}
默认 | Alignment.topRight |
---|---|
Stack normal.png | Stack topRight.png |
4.3 clipBehavior 剪切方式
Stack _stack(){
return Stack(
// alignment: Alignment.topRight,
clipBehavior: Clip.none,
// textDirection: TextDirection.rtl,
// overflow: Overflow.visible,
// fit: StackFit.loose,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
ConstrainedBox(
constraints: BoxConstraints(),
child: Text("一行文字", style: TextStyle(backgroundColor: Colors.yellow),),
),
_positionedForAll(),
_positionedForLeftTop(),
_positionedForClip(),
],
);
}
默认 | Clip.none |
---|---|
Stack normal.png | Stack clip none.png |
4.4 textDirection 布局方向
Stack _stack(){
return Stack(
// alignment: Alignment.topRight,
// clipBehavior: Clip.none,
textDirection: TextDirection.rtl,
// overflow: Overflow.visible,
// fit: StackFit.loose,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
ConstrainedBox(
constraints: BoxConstraints(),
child: Text("一行文字", style: TextStyle(backgroundColor: Colors.yellow),),
),
_positionedForAll(),
_positionedForLeftTop(),
_positionedForClip(),
],
);
}
默认 | TextDirection.rtl |
---|---|
Stack normal.png | Stack rtl.png |
4.5 overflow
子控件边缘超出 Stack 边缘的部分是否裁剪,默认为 Overflow.clip
Stack _stack(){
return Stack(
// alignment: Alignment.topRight,
// clipBehavior: Clip.none,
// textDirection: TextDirection.rtl,
overflow: Overflow.visible,
// fit: StackFit.loose,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
ConstrainedBox(
constraints: BoxConstraints(),
child: Text("一行文字", style: TextStyle(backgroundColor: Colors.yellow),),
),
_positionedForAll(),
_positionedForLeftTop(),
_positionedForClip(),
],
);
}
默认 | Overflow.visible |
---|---|
Stack normal.png | Stack Overflow visible.png |
4.6 fit 填充方式
Stack _stack(){
return Stack(
// alignment: Alignment.topRight,
// clipBehavior: Clip.none,
// textDirection: TextDirection.rtl,
// overflow: Overflow.visible,
fit: StackFit.expand,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
ConstrainedBox(
constraints: BoxConstraints(),
child: Text("一行文字", style: TextStyle(backgroundColor: Colors.yellow),),
),
_positionedForAll(),
_positionedForLeftTop(),
_positionedForClip(),
],
);
}
默认 | StackFit.expand |
---|---|
Stack normal.png | StackFit.expand.png |
5. 技术小结
- 绝对布局是一种最简单实用的布局方式,可控性非常强。
- Row、Column、Stack 三种掌握了之后基本就可以完成所有的页面排版。
网友评论