垂直和(hé)水(shuǐ)平放(fàng)置多個widget
最常見的布局模式之一是垂直或水(shuǐ)平排列widget。您可以使用(yòng)行(Row)水(shuǐ)平排列widget,并使用(yòng)列(Column)垂直排列widget。
重點是什(shén)麽?
行和(hé)列是兩種最常用(yòng)的布局模式。
行和(hé)列都需要一個子widget列表。
子widget本身可以是行、列或其他(tā)複雜(zá)widget。
您可以指定行或列如何在垂直或水(shuǐ)平方向上(shàng)對(duì)齊其子項
您可以拉伸或限制特定的子widget.
您可以指定子widget如何使用(yòng)行或列的可用(yòng)空(kōng)間.
要在Flutter中創建行或列,可以将一個widget列表添加到(dào)Row 或Column 中。 同時(shí),每個孩子本身可以是一個Row或一個Column,依此類推。以下(xià)示例顯示如何在行或列内嵌套行或列。
注意:行和(hé)列是水(shuǐ)平和(hé)垂直布局的基本、低(dī)級widget - 這(zhè)些(xiē)低(dī)級widget允許最大(dà)化的自(zì)定義。Flutter還提供專門(mén)的,更高(gāo)級别的widget,可能(néng)足以滿足您的需求。 例如,您可能(néng)更喜歡ListTile而不是Row,ListTile是一個易于使用(yòng)的小(xiǎo)部件,具有前後圖标屬性以及最多3行文(wén)本。您可能(néng)更喜歡ListView而不是列,ListView是一種列狀布局,如果其内容太長而無法适應可用(yòng)空(kōng)間,則會(huì)自(zì)動滾動。 有關更多信息,請(qǐng)參閱通用(yòng)布局widget。
對(duì)齊 widgets
您可以控制行或列如何使用(yòng)mainAxisAlignment和(hé)crossAxisAlignment屬性來(lái)對(duì)齊其子項。 對(duì)于行(Row)來(lái)說,主軸是水(shuǐ)平方向,橫軸垂直方向。對(duì)于列(Column)來(lái)說,主軸垂直方向,橫軸水(shuǐ)平方向。
MainAxisAlignment 和(hé)CrossAxisAlignment 類提供了(le)很(hěn)多控制對(duì)齊的常量.
注意: 将圖片添加到(dào)項目時(shí),需要更新pubspec文(wén)件才能(néng)訪問它們 - 此示例使用(yòng)Image.asset顯示圖像。 有關更多信息,請(qǐng)參閱此示例的pubspec.yaml文(wén)件, 或在Flutter中添加資源和(hé)圖像。如果您使用(yòng)的是網上(shàng)的圖片,則不需要執行此操作(zuò),使用(yòng)Image.network即可。
在以下(xià)示例中,3個圖像中的每一個都是100像素寬。渲染盒(在這(zhè)種情況下(xià),整個屏幕)寬度超過300個像素, 因此設置主軸對(duì)齊方式爲spaceEvenly,它會(huì)在每個圖像之間,之前和(hé)之後均勻分配空(kōng)閑的水(shuǐ)平空(kōng)間。
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Image.asset('images/pic1.jpg'),
Dart code: main.dartImages: imagesPubspec: pubspec.yaml
列的工(gōng)作(zuò)方式與行相同。以下(xià)示例顯示了(le)一列,包含3個圖片,每個圖片高(gāo)100個像素。 渲染盒(在這(zhè)種情況下(xià),整個屏幕)的高(gāo)度大(dà)于300像素,因此設置主軸對(duì)齊方式爲spaceEvenly,它會(huì)在每個圖像之間,上(shàng)方和(hé)下(xià)方均勻分配空(kōng)閑的垂直空(kōng)間。
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Image.asset('images/pic1.jpg'),
Dart code: main.dartImages: imagesPubspec: pubspec.yaml
調整 widget
也(yě)許你(nǐ)想要一個widget占據其兄弟widget兩倍的空(kōng)間。您可以将行或列的子項放(fàng)置在Expandedwidget中, 以控制沿着主軸方向的widget大(dà)小(xiǎo)。Expanded widget具有一個flex屬性,它是一個整數,用(yòng)于确定widget的彈性系數,默認彈性系數是1。
例如,要創建一個由三個widget組成的行,其中中間widget的寬度是其他(tā)兩個widget的兩倍,将中間widget的彈性系數設置爲2:
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new Expanded(
child: new Image.asset('images/pic1.jpg'),
),
new Expanded(
flex: 2,
child: new Image.asset('images/pic2.jpg'),
),
new Expanded(
a row of 3 images with the middle image twice as wide as the others
Dart code: main.dartImages: imagesPubspec: pubspec.yaml
要修複上(shàng)一節中的示例:其中一行有3張圖片,行對(duì)于其渲染框太寬,并且導緻右邊出現(xiàn)紅(hóng)色條中的問題,可以使用(yòng)Expanded widget來(lái)包裝每個widget。 默認情況下(xià),每個widget的彈性系數爲1,将行的三分之一分配給每個小(xiǎo)部件。
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new Expanded(
child: new Image.asset('images/pic1.jpg'),
),
new Expanded(
child: new Image.asset('images/pic2.jpg'),
),
new Expanded(
聚集 widgets
默認情況下(xià),行或列沿着其主軸會(huì)盡可能(néng)占用(yòng)盡可能(néng)多的空(kōng)間,但(dàn)如果要将孩子緊密聚集在一起,可以将mainAxisSize設置爲MainAxisSize.min。 以下(xià)示例使用(yòng)此屬性将星形圖标聚集在一起(如果不聚集,五張星形圖标會(huì)分散開(kāi))。
class _MyHomePageState extends State
@override
Widget build(BuildContext context) {
var packedRow = new Row(
mainAxisSize: MainAxisSize.min,
children: [
new Icon(Icons.star, color: Colors.green[500]),
new Icon(Icons.star, color: Colors.green[500]),
new Icon(Icons.star, color: Colors.green[500]),
new Icon(Icons.star, color: Colors.black),
new Icon(Icons.star, color: Colors.black),
],
);
// ...
}
嵌套行和(hé)列
布局框架允許您根據需要在行和(hé)列内部再嵌套行和(hé)列。
該ratings變量創建一個包含5個星形圖标和(hé)一個文(wén)本的行:
class _MyHomePageState extends State
@override
Widget build(BuildContext context) {
//...
var ratings = new Container(
padding: new EdgeInsets.all(20.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Row(
mainAxisSize: MainAxisSize.min,
children: [
new Icon(Icons.star, color: Colors.black),
new Icon(Icons.star, color: Colors.black),
new Icon(Icons.star, color: Colors.black),
new Icon(Icons.star, color: Colors.black),
new Icon(Icons.star, color: Colors.black),
],
),
new Text(
'170 Reviews',
style: new TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20.0,
),
),
],
),
);
//...
}
}
提示: 爲了(le)最大(dà)限度地減少由嵌套嚴重的布局代碼導緻的視(shì)覺混淆,可以在變量和(hé)函數中實現(xiàn)UI的各個部分。
該iconList變量定義了(le)圖标行:
class _MyHomePageState extends State
@override
Widget build(BuildContext context) {
// ...
var descTextStyle = new TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 18.0,
height: 2.0,
);
// DefaultTextStyle.merge可以允許您創建一個默認的文(wén)本樣式,該樣式會(huì)被其
// 所有的子節點繼承
var iconList = DefaultTextStyle.merge(
style: descTextStyle,
child: new Container(
padding: new EdgeInsets.all(20.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Column(
children: [
new Icon(Icons.kitchen, color: Colors.green[500]),
new Text('PREP:'),
new Text('25 min'),
],
),
new Column(
children: [
new Icon(Icons.timer, color: Colors.green[500]),
new Text('COOK:'),
new Text('1 hr'),
],
),
new Column(
children: [
new Icon(Icons.restaurant, color: Colors.green[500]),
new Text('FEEDS:'),
new Text('4-6'),
],
),
],
),
),
);
// ...
}
}
該leftColumn變量包含評分和(hé)圖标行,以及描述Pavlova的标題和(hé)文(wén)字:
class _MyHomePageState extends State
@override
Widget build(BuildContext context) {
//...
var leftColumn = new Container(
padding: new EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
child: new Column(
children: [
titleText,
subTitle,
ratings,
iconList,
],
),
);
//...
}
}
左列放(fàng)置在容器中以約束其寬度。最後,用(yòng)整個行(包含左列和(hé)圖像)放(fàng)置在一個Card内構建UI:
Pavlova圖片來(lái)自(zì) Pixabay ,可以在Creative Commons許可下(xià)使用(yòng)。 您可以使用(yòng)Image.network直接從(cóng)網上(shàng)下(xià)載顯示圖片,但(dàn)對(duì)于此示例,圖像保存到(dào)項目中的圖像目錄中,添加到(dào)pubspec文(wén)件, 并使用(yòng)Images.asset。 有關更多信息,請(qǐng)參閱在Flutter中添加Asserts和(hé)圖片。
body: new Center(
child: new Container(
margin: new EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 30.0),
height: 600.0,
child: new Card(
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Container(
width: 440.0,
child: leftColumn,
),
mainImage,
],
),
),
),
),
Dart code: main.dartImages: imagesPubspec: pubspec.yaml
提示: Pavlova示例在廣泛的橫屏設備(如平闆電腦(nǎo))上(shàng)運行最佳。如果您在iOS模拟器中運行此示例, 則可以使用(yòng)Hardware > Device菜單選擇其他(tā)設備。對(duì)于這(zhè)個例子,我們推薦iPad Pro。 您可以使用(yòng)Hardware > Rotate将其方向更改爲橫向模式 。您還可以使用(yòng)Window > Scale更改模拟器窗口的大(dà)小(xiǎo)(不更改邏輯像素的數量)
網站(zhàn)建設開(kāi)發|APP設計(jì)開(kāi)發|小(xiǎo)程序建設開(kāi)發