1、Stack
Stack Stack({
Key? key,
//用于指定子控件的对齐方式,可以是左上角、居中、右下角等。
AlignmentGeometry alignment = AlignmentDirectional.topStart,
//子 Widget 的排列方式,默认值是 TextDirection.ltr。
TextDirection? textDirection,
//用于指定未定位子控件的大小调整方式,可以是填充、缩放或保持原始大小。
StackFit fit = StackFit.loose,
//剪辑小部件内容
Clip clipBehavior = Clip.hardEdge,
List<Widget> children = const <Widget>[],
})
示例
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
const Text(
"我是一段文字",
style: TextStyle(fontSize: 30, color: Colors.green),
)
],
),
);
}
}
2、Align
Align 组件可以调整子组件的位置 , Stack 组件中结合 Align 组件也可以控制每个子元素的显示位置。
Align Align({
Key? key,
//用于指定子控件的对齐方式.
AlignmentGeometry alignment = Alignment.center,
//指定子控件的宽度相对于父控件宽度的比例因子。取值范围为0.0到1.0。
double? widthFactor,
//指定子控件的高度相对于父控件高度的比例因子。取值范围为0.0到1.0。
double? heightFactor,
Widget? child,
})
示例
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 200,
height: 200,
color: Colors.lightBlue,
child: const Align(
// alignment: Alignment.center,
alignment: Alignment(1, 1),
child: FlutterLogo(
size: 100,
),
),
);
}
}
Alignment Widget:
1、Alignment Widget 会以矩形的中心点作为坐标原点,即 Alignment(0.0, 0.0) 。
2、 x 的值从 -1 到 1 代表矩形左边到右边的距离,y 的值从 -1 到 1 代表矩形顶部到底边的距离,因此 2 个水平(或垂直)单位则等于矩形的宽(或高)。如 Alignment(-1.0, -1.0) 代表矩形的左侧顶点, Alignment(1.0, 1.0) 代表右侧底部终点, Alignment(1.0, -1.0) 则正是右侧顶点。
3、为了使用方便,矩形的原点、四个顶点,以及四条边的终点在 Alignment 类中都已经定义为了静态常量。
4、Alignment 可以通过其坐标转换公式将其坐标转为子元素的具体偏移坐标:
//childWidth 为子元素的宽度, childHeight 为子元素高度。
(Alignment.x*childWidth/2+childWidth/2, Alignment.y*childHeight/2+childHeight/2)
5、Center 继承自 Align ,它比 Align 只少了一个 alignment 参数。由于 Align 的构造函数中
alignment 值为 Alignment.center ,所以,我们可以认为 Center 组件其实是对齐方式确定。
Align 结合 Stack 组件
///Align 结合 Stack 组件
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 300,
width: 300,
color: Colors.lightGreen,
child: const Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment(1, -1),
child: Icon(
Icons.home,
size: 40,
color: Colors.white,
),
),
Align(
alignment: Alignment.center,
child: Icon(
Icons.search,
size: 40,
color: Colors.white,
),
),
Align(
alignment: Alignment.bottomRight,
child: Icon(
Icons.settings,
size: 40,
color: Colors.white,
),
)
],
),
),
);
}
}
3、Positioned
Stack 组件中结合 Positioned 组件也可以控制每个子元素的显示位置。
Positioned Positioned({
Key? key,
//子元素距离左侧距离
double? left,
//子元素距离顶部的距离
double? top,
//子元素距离右侧距离
double? right,
//子元素距离底部的距离
double? bottom,
//组件的高度 (注意:宽度和高度必须是固定值,没法使用double.infinity)
double? width,
//子组件的高度
double? height,
required Widget child,
})
示例
///Positioned
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
child: const Stack(
// alignment: Alignment.center,
children: [
Positioned(
left: 10,
child: Icon(
Icons.home,
size: 40,
color: Colors.white,
)),
Positioned(
bottom: 5,
child: Icon(
Icons.search,
size: 40,
color: Colors.white,
)),
Positioned(
right: 15,
child: Icon(
Icons.settings,
size: 40,
color: Colors.white,
)),
Positioned(
top: 20,
child: Icon(
Icons.memory,
size: 40,
color: Colors.white,
)),
],
),
),
);
}
}
Stack Positioned 案例
class MyApp extends StatelessWidget {
const MyApp({super.key});
List<Widget> _customList() {
List<Widget> list = [];
for (var i = 0; i < 30; i++) {
list.add(
ListTile(
title: Text("第 $i 个数据"),
),
);
}
return list;
}
@override
Widget build(BuildContext context) {
//获取屏幕的宽高
final Size size = MediaQuery.sizeOf(context);
return Stack(
children: [
ListView(
padding: const EdgeInsets.only(top: 45),
children: _customList(),
),
Positioned(
top: 0,
left: 0,
height: 40,
width: size.width,
child: Container(
alignment: Alignment.center,
color: Colors.black,
child: const Text(
"Hello Flutter",
style: TextStyle(fontSize: 20, color: Colors.white),
),
)),
],
);
}
}
补充:MediaQuery:获取屏幕宽度和高度
final Size size = MediaQuery.of(context).size;
print("宽: ${size.width} -- 高: ${size.height}");
网友评论