介紹
層疊布局和Web中的絕對定位、Android中的Frame布局是相似的玖喘,子組件可以根據(jù)距父容器四個角的位置來確定自身的位置甩牺。絕對定位允許子組件堆疊起來(按照代碼中聲明的順序)。Flutter中使用Stack和Positioned這兩個組件來配合實現(xiàn)絕對定位累奈。Stack允許子組件堆疊贬派,而Positioned用于根據(jù)Stack的四個角來確定子組件的位置。
先簡單使用下Stack
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "demo",
home: Scaffold(
appBar: AppBar(title: Text("bar")),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Stack(
children: [
Container(
height: 300,
width: 300,
color: Colors.blue[200],
),
Text("一段文字")
],
));
}
}
可以發(fā)現(xiàn)澎媒,正常情況下搞乏,當(dāng)Text和Container組件并排時,文字會出現(xiàn)在盒子的后面旱幼,但是使用了stack后查描,文字與盒子出現(xiàn)在同一區(qū)域(其實是文字在盒子上面)。
參數(shù)列表
Stack({
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
-
alignment
:此參數(shù)決定如何去對齊沒有定位(沒有使用Positioned
)或部分定位的子組件柏卤。所謂部分定位冬三,在這里特指沒有在某一個軸上定位:left
、right
為橫軸缘缚,top
勾笆、bottom
為縱軸,只要包含某個軸上的一個定位屬性就算在該軸上有定位桥滨。 -
textDirection
:和Row
窝爪、Wrap
的textDirection
功能一樣,都用于確定alignment
對齊的參考系齐媒,即:textDirection
的值為TextDirection.ltr
蒲每,則alignment
的start
代表左,end
代表右喻括,即從左往右
的順序邀杏;textDirection
的值為TextDirection.rtl
,則alignment的start
代表右唬血,end
代表左望蜡,即從右往左
的順序唤崭。 -
fit
:此參數(shù)用于確定沒有定位的子組件如何去適應(yīng)Stack
的大小。StackFit.loose
表示使用子組件的大小脖律,StackFit.expand
表示擴伸到Stack
的大小谢肾。 -
overflow
:此屬性決定如何顯示超出Stack
顯示空間的子組件;值為Overflow.clip
時小泉,超出部分會被剪裁(隱藏)芦疏,值為Overflow.visible
時則不會。
Positioned
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
left膏孟、top 眯分、right拌汇、 bottom分別代表離Stack左柒桑、上、右噪舀、底四邊的距離魁淳。width和height用于指定需要定位元素的寬度和高度。注意与倡,Positioned的width界逛、height 和其它地方的意義稍微有點區(qū)別,此處用于配合left纺座、top 息拜、right、 bottom來定位組件净响,舉個例子少欺,在水平方向時,你只能指定left馋贤、right赞别、width三個屬性中的兩個,如指定left和width后配乓,right會自動算出(left+width)仿滔,如果同時指定三個屬性則會報錯,垂直方向同理犹芹。
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "demo",
home: Scaffold(
appBar: AppBar(title: Text("bar")),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Container(
width: 300,
height: 300,
color: Colors.blue[200],
child: Stack(
children: <Widget>[
Positioned(
left: 0,
top: 0,
child: Icon(Icons.home),
),
Positioned(
right: 0,
bottom: 0,
child: Icon(Icons.home),
),
Positioned(
left: 150,
top: 150,
child: Icon(Icons.home),
)
],
),
));
}
}
注意要考慮元素自身的大小
Align
參數(shù)列表
Align({
Key key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget child,
})
-
alignment
: 需要一個AlignmentGeometry
類型的值崎页,表示子組件在父組件中的起始位置。AlignmentGeometry
是一個抽象類腰埂,它有兩個常用的子類:Alignment
和FractionalOffset
飒焦,我們將在下面的示例中詳細(xì)介紹。 -
widthFactor
和heightFactor
是用于確定Align
組件本身寬高的屬性盐固;它們是兩個縮放因子荒给,會分別乘以子元素的寬丈挟、高,最終的結(jié)果就是Align
組件的寬高志电。如果值為null
曙咽,則組件的寬高將會占用盡可能多的空間。
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "demo",
home: Scaffold(
appBar: AppBar(title: Text("bar")),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Container(
width: 300,
height: 300,
color: Colors.blue[200],
child: Stack(
children: <Widget>[
Align(
alignment: Alignment(1, 1),
child: Icon(Icons.home),
),
Align(
alignment: Alignment(0, 0),
child: Icon(Icons.home),
),
Align(
alignment: Alignment(-1, -1),
child: Icon(Icons.home),
)
],
),
));
}
}