垂直和(hé)水平放置多個widget
最常見(jiàn)的布局模式之一(yī)是垂直或水平排列widget。您可(kě)以使用行(xíng)(Row)水平排列widget,并使用列(Column)垂直排列widget。
重點是什麽?
行(xíng)和(hé)列是兩種最常用的布局模式。
行(xíng)和(hé)列都(dōu)需要(yào)一(yī)個子widget列表。
子widget本身可(kě)以是行(xíng)、列或其他(tā)複雜(zá)widget。
您可(kě)以指定行(xíng)或列如(rú)何在垂直或水平方向上(shàng)對齊其子項
您可(kě)以拉伸或限制特定的子widget.
您可(kě)以指定子widget如(rú)何使用行(xíng)或列的可(kě)用空間(jiān).
要(yào)在Flutter中創建行(xíng)或列,可(kě)以将一(yī)個widget列表添加到Row 或Column 中。 同時(shí),每個孩子本身可(kě)以是一(yī)個Row或一(yī)個Column,依此類推。以下(xià)示例顯示如(rú)何在行(xíng)或列內(nèi)嵌套行(xíng)或列。
注意:行(xíng)和(hé)列是水平和(hé)垂直布局的基本、低(dī)級widget - 這(zhè)些低(dī)級widget允許最大化的自(zì)定義。Flutter還提供專門的,更高級别的widget,可(kě)能(néng)足以滿足您的需求。 例如(rú),您可(kě)能(néng)更喜歡ListTile而不是Row,ListTile是一(yī)個易于使用的小部件,具有前後圖标屬性以及最多3行(xíng)文本。您可(kě)能(néng)更喜歡ListView而不是列,ListView是一(yī)種列狀布局,如(rú)果其內(nèi)容太長(cháng)而無法适應可(kě)用空間(jiān),則會自(zì)動滾動。 有關更多信息,請(qǐng)參閱通(tōng)用布局widget。
對齊 widgets
您可(kě)以控制行(xíng)或列如(rú)何使用mainAxisAlignment和(hé)crossAxisAlignment屬性來對齊其子項。 對于行(xíng)(Row)來說,主軸是水平方向,橫軸垂直方向。對于列(Column)來說,主軸垂直方向,橫軸水平方向。
MainAxisAlignment 和(hé)CrossAxisAlignment 類提供了(le)很(hěn)多控制對齊的常量.
注意: 将圖片添加到項目時(shí),需要(yào)更新pubspec文件才能(néng)訪問(wèn)它們 - 此示例使用Image.asset顯示圖像。 有關更多信息,請(qǐng)參閱此示例的pubspec.yaml文件, 或在Flutter中添加資源和(hé)圖像。如(rú)果您使用的是網上(shàng)的圖片,則不需要(yào)執行(xíng)此操作(zuò),使用Image.network即可(kě)。
在以下(xià)示例中,3個圖像中的每一(yī)個都(dōu)是100像素寬。渲染盒(在這(zhè)種情況下(xià),整個屏幕)寬度超過300個像素, 因此設置主軸對齊方式為(wèi)spaceEvenly,它會在每個圖像之間(jiān),之前和(hé)之後均勻分配空閑的水平空間(jiān)。
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ò)方式與行(xíng)相同。以下(xià)示例顯示了(le)一(yī)列,包含3個圖片,每個圖片高100個像素。 渲染盒(在這(zhè)種情況下(xià),整個屏幕)的高度大于300像素,因此設置主軸對齊方式為(wèi)spaceEvenly,它會在每個圖像之間(jiān),上(shàng)方和(hé)下(xià)方均勻分配空閑的垂直空間(jiān)。
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ào)一(yī)個widget占據其兄弟widget兩倍的空間(jiān)。您可(kě)以将行(xíng)或列的子項放置在Expandedwidget中, 以控制沿着主軸方向的widget大小。Expanded widget具有一(yī)個flex屬性,它是一(yī)個整數(shù),用于确定widget的彈性系數(shù),默認彈性系數(shù)是1。
例如(rú),要(yào)創建一(yī)個由三個widget組成的行(xíng),其中中間(jiān)widget的寬度是其他(tā)兩個widget的兩倍,将中間(jiān)widget的彈性系數(shù)設置為(wèi)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
要(yào)修複上(shàng)一(yī)節中的示例:其中一(yī)行(xíng)有3張圖片,行(xíng)對于其渲染框太寬,并且導緻右邊出現紅(hóng)色條中的問(wèn)題,可(kě)以使用Expanded widget來包裝每個widget。 默認情況下(xià),每個widget的彈性系數(shù)為(wèi)1,将行(xíng)的三分之一(yī)分配給每個小部件。
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à),行(xíng)或列沿着其主軸會盡可(kě)能(néng)占用盡可(kě)能(néng)多的空間(jiān),但(dàn)如(rú)果要(yào)将孩子緊密聚集在一(yī)起,可(kě)以将mainAxisSize設置為(wèi)MainAxisSize.min。 以下(xià)示例使用此屬性将星形圖标聚集在一(yī)起(如(rú)果不聚集,五張星形圖标會分散開(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),
],
);
// ...
}
嵌套行(xíng)和(hé)列
布局框架允許您根據需要(yào)在行(xíng)和(hé)列內(nèi)部再嵌套行(xíng)和(hé)列。
該ratings變量創建一(yī)個包含5個星形圖标和(hé)一(yī)個文本的行(xíng):
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,
),
),
],
),
);
//...
}
}
提示: 為(wèi)了(le)最大限度地(dì)減少(shǎo)由嵌套嚴重的布局代碼導緻的視(shì)覺混淆,可(kě)以在變量和(hé)函數(shù)中實現UI的各個部分。
該iconList變量定義了(le)圖标行(xíng):
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可(kě)以允許您創建一(yī)個默認的文本樣式,該樣式會被其
// 所有的子節點繼承
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é)圖标行(xíng),以及描述Pavlova的标題和(hé)文字:
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,
],
),
);
//...
}
}
左列放置在容器中以約束其寬度。最後,用整個行(xíng)(包含左列和(hé)圖像)放置在一(yī)個Card內(nèi)構建UI:
Pavlova圖片來自(zì) Pixabay ,可(kě)以在Creative Commons許可(kě)下(xià)使用。 您可(kě)以使用Image.network直接從(cóng)網上(shàng)下(xià)載顯示圖片,但(dàn)對于此示例,圖像保存到項目中的圖像目錄中,添加到pubspec文件, 并使用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示例在廣泛的橫屏設備(如(rú)平闆電腦)上(shàng)運行(xíng)最佳。如(rú)果您在iOS模拟器中運行(xíng)此示例, 則可(kě)以使用Hardware > Device菜單選擇其他(tā)設備。對于這(zhè)個例子,我們推薦iPad Pro。 您可(kě)以使用Hardware > Rotate将其方向更改為(wèi)橫向模式 。您還可(kě)以使用Window > Scale更改模拟器窗口的大小(不更改邏輯像素的數(shù)量)
網站建設開(kāi)發|APP設計開(kāi)發|小程序建設開(kāi)發