Flutter學習指南:UI佈局和控制元件

singwhatiwanna發表於2018-10-30
color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>這是一個系列,通過8篇文章幫助大家建立起 Flutter 的知識體系,建議大家好好閱讀並收藏起來。本篇文章我們先介紹 Flutter 裡一些常用的 UI 控制元件,然後藉助官網提供的兩個 demo 把所學的控制元件知識實際使用起來。

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>基本控制元件

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>Widget

color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>Widget 分為兩種,一種是無狀態的,叫 StatelessWidget,它只能用來展示資訊,不能有動作(使用者互動);另一種是有狀態的,叫 StatefulWidget,這種 Widget 可以通過改變狀態使得 UI 發生變化,它可以包含使用者互動。

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
FooWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
// 
...

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>StatefulWidget 用起來麻煩一些,他還需要一個 State:
class 
BarWidget 
extends 
StatefulWidget 
{
 
 
@override
 
 
State 
createState() 
{
 
 
 
 
return 
_BarWidgetState();

 
 

}

}

class 
_BarWidgetState 
extends 
State<
BarWidget>
 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
// 
...

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>從 BarWidget 的實現來看,好像跟前面使用 StatelessWidget 沒有什麼區別,都是在 build 方法裡面返回一個 Widget,只是 stateful widget 把這個方法挪到了 State 裡面。實際上,兩者的區別非常大。stateless widget 整個生命週期裡都不會改變,所以 build 方法只會執行一次。而 stateful widget 只要狀態改變,就會呼叫 build 方法重新建立 UI。

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
BarWidget 
extends 
StatefulWidget 
{
 
 
@override
 
 
State 
createState() 
{
 
 
 
 
return 
_BarWidgetState();

 
 

}

}

class 
_BarWidgetState 
extends 
State<
BarWidget>
 
{
 
 
var 


0;


 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Row(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Text('i 

$i'
),
 
 
 
 
 
 
 
 
RaisedButton(
 
 
 
 
 
 
 
 
 
 
onPressed: 
() 
{
 
 
 
 
 
 
 
 
 
 
 
 
setState(() 
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
++i;

 
 
 
 
 
 
 
 
 
 
 
 

});

 
 
 
 
 
 
 
 
 
 

},
 
 
 
 
 
 
 
 
 
 
child: 
Text('click'),
 
 
 
 
 
 
 
 
)
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>文字

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Text("Put 
your 
text 
here"
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Text(
 
 
 
 
 
 
"Put 
your 
text 
here"
,
 
 
 
 
 
 
style: 
TextStyle(
 
 
 
 
 
 
 
 
color: 
Colors.blue,
 
 
 
 
 
 
 
 
fontSize: 
16.0,
 
 
 
 
 
 
 
 
fontWeight: 
FontWeight.bold
 
 
 
 
 
 
),
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>圖片

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">Image.asset(name);

Image.file(file);

Image.memory(bytes);

Image.network(src);

複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Image.network(
 
 
 
 
 
 
"http://www.example.com/xxx.png",
 
 
 
 
 
 
width: 
200.0,
 
 
 
 
 
 
height: 
150.0,
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>按鈕

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
var 
flatBtn 

FlatButton(
 
 
 
 
 
 
onPressed: 
() 
=>
 
print('FlatButton 
pressed'
),
 
 
 
 
 
 
child: 
Text('BUTTON'),
 
 
 
 
);

 
 
 
 
var 
raisedButton 

RaisedButton(
 
 
 
 
 
 
onPressed: 
() 
=>
 
print('RaisedButton 
pressed'
),
 
 
 
 
 
 
child: 
Text('BUTTON'),
 
 
 
 
);

 
 
 
 
return 
raisedButton;

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>注意,由於我們只是在按鈕點選的時候列印一個字串,這裡使用 StatelessWidget 是沒有問題的。但如果有其他 UI 動作(比如彈出一個 dialog,則必須使用 StatefulWidget)。

color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>FlatButton:
margin: 0px;
padding: 0px;
margin-top: 10px;
text-align: center;
color: rgb(153, 153, 153);
font-size: 0.7em;
“>flat-button

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>raised-button margin: 0px;
padding: 0px;
margin-top: 10px;
text-align: center;
color: rgb(153, 153, 153);
font-size: 0.7em;
“>raised-button

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>文字輸入框

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
MessageForm 
extends 
StatefulWidget 
{
 
 
@override
 
 
State 
createState() 
{
 
 
 
 
return 
_MessageFormState();

 
 

}

}

class 
_MessageFormState 
extends 
State<
MessageForm>
 
{
 
 
var 
editController 

TextEditingController();


 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
// 
Row、Expand 
都是用於佈局的控制元件,這裡可以先忽略它們

 
 
 
 
return 
Row(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Expanded(
 
 
 
 
 
 
 
 
 
 
child: 
TextField(
 
 
 
 
 
 
 
 
 
 
 
 
controller: 
editController,
 
 
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
RaisedButton(
 
 
 
 
 
 
 
 
 
 
child: 
Text("click"),
 
 
 
 
 
 
 
 
 
 
onPressed: 
() 
=>
 
print('text 
inputted: 
${editController.text
}
'
),
 
 
 
 
 
 
 
 
)
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

 
 
@override
 
 
void 
dispose() 
{
 
 
 
 
super.dispose();

 
 
 
 
// 
手動呼叫 
controller 
的 
dispose 
方法以釋放資源

 
 
 
 
editController.dispose();

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>顯示彈框

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
_MessageFormState 
extends 
State<
MessageForm>
 
{
 
 
var 
editController 

TextEditingController();


 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Row(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Expanded(
 
 
 
 
 
 
 
 
 
 
child: 
TextField(
 
 
 
 
 
 
 
 
 
 
 
 
controller: 
editController,
 
 
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
RaisedButton(
 
 
 
 
 
 
 
 
 
 
child: 
Text("click"),
 
 
 
 
 
 
 
 
 
 
onPressed: 
() 
{
 
 
 
 
 
 
 
 
 
 
 
 
showDialog(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 
第一個 
context 
是引數名,第二個 
context 
是 
State 
的成員變數

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
context: 
context,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
builder: 
(_) 
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
return 
AlertDialog(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 
dialog 
的內容

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
content: 
Text(editController.text),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 
actions 
設定 
dialog 
的按鈕

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
actions: 
<
Widget>
[
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
FlatButton(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
child: 
Text('OK'),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 
使用者點選按鈕後,關閉彈框

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
onPressed: 
() 
=>
 
Navigator.pop(context),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
);

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

}
 
 
 
 
 
 
 
 
 
 
 
 
);

 
 
 
 
 
 
 
 
 
 

}
 
 
 
 
 
 
 
 
)
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

 
 
@override
 
 
void 
dispose() 
{
 
 
 
 
super.dispose();

 
 
 
 
editController.dispose();

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>最簡單的佈局——Container、Padding 和 Center:

color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.5em 0px;
“>控制元件 Container 可以讓我們設定一個控制元件的尺寸、背景、margin 等:
class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Container(
 
 
 
 
 
 
child: 
Text('text'),
 
 
 
 
 
 
padding: 
EdgeInsets.all(8.0),
 
 
 
 
 
 
margin: 
EdgeInsets.all(4.0),
 
 
 
 
 
 
width: 
80.0,
 
 
 
 
 
 
decoration: 
BoxDecoration(
 
 
 
 
 
 
 
 
// 
背景色

 
 
 
 
 
 
 
 
color: 
Colors.grey,
 
 
 
 
 
 
 
 
// 
圓角

 
 
 
 
 
 
 
 
borderRadius: 
BorderRadius.circular(5.0),
 
 
 
 
 
 
),
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Padding(
 
 
 
 
 
 
padding: 
EdgeInsets.all(8.0),
 
 
 
 
 
 
child: 
Text('text'),
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Container(
 
 
 
 
 
 
padding: 
EdgeInsets.all(8.0),
 
 
 
 
 
 
margin: 
EdgeInsets.all(4.0),
 
 
 
 
 
 
width: 
200.0,
 
 
 
 
 
 
height: 
200.0,
 
 
 
 
 
 
decoration: 
BoxDecoration(
 
 
 
 
 
 
 
 
// 
背景色

 
 
 
 
 
 
 
 
color: 
Colors.grey,
 
 
 
 
 
 
 
 
// 
圓角

 
 
 
 
 
 
 
 
borderRadius: 
BorderRadius.circular(5.0),
 
 
 
 
 
 
),

 
 
 
 
 
 
// 
把文字放在 
Container 
的中間

 
 
 
 
 
 
child: 
Center(
 
 
 
 
 
 
 
 
child: 
Text('text'),
 
 
 
 
 
 
),
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>水平、豎直佈局和 Expand

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Row(
 
 
 
 
 
 
// 
只有一個子元素的 
widget,一般使用 
child 
引數來設定;Row 
可以包含多個子控制元件,

 
 
 
 
 
 
// 
對應的則是 
children。

 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Text('text1'),
 
 
 
 
 
 
 
 
Text('text2'),
 
 
 
 
 
 
 
 
Text('text3'),
 
 
 
 
 
 
 
 
Text('text4'),
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Column(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Text('text1'),
 
 
 
 
 
 
 
 
Text('text2'),
 
 
 
 
 
 
 
 
Text('text3'),
 
 
 
 
 
 
 
 
Text('text4'),
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
MessageForm 
extends 
StatefulWidget 
{
 
 
@override
 
 
State 
createState() 
{
 
 
 
 
return 
_MessageFormState();

 
 

}

}

class 
_MessageFormState 
extends 
State<
MessageForm>
 
{
 
 
var 
editController 

TextEditingController();


 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Row(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
// 
佔滿一行裡除 
RaisedButton 
外的所有空間

 
 
 
 
 
 
 
 
Expanded(
 
 
 
 
 
 
 
 
 
 
child: 
TextField(
 
 
 
 
 
 
 
 
 
 
 
 
controller: 
editController,
 
 
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
RaisedButton(
 
 
 
 
 
 
 
 
 
 
child: 
Text("click"),
 
 
 
 
 
 
 
 
 
 
onPressed: 
() 
=>
 
print('text 
inputted: 
${editController.text
}
'
),
 
 
 
 
 
 
 
 
)
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

 
 
@override
 
 
void 
dispose() 
{
 
 
 
 
super.dispose();

 
 
 
 
editController.dispose();

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Row(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Expanded(
 
 
 
 
 
 
 
 
 
 
// 
佔一行的 
2/3

 
 
 
 
 
 
 
 
 
 
flex: 
2,
 
 
 
 
 
 
 
 
 
 
child: 
RaisedButton(child: 
Text('btn1'),),
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
Expanded(
 
 
 
 
 
 
 
 
 
 
// 
佔一行的 
1/3

 
 
 
 
 
 
 
 
 
 
flex: 
1,
 
 
 
 
 
 
 
 
 
 
child: 
RaisedButton(child: 
Text('btn2'),),
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>Stack 佈局

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Stack(
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Text('foobar'),
 
 
 
 
 
 
 
 
Text('barfoo'),
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
">class 
TestWidget 
extends 
StatelessWidget 
{
 
 
@override
 
 
Widget 
build(BuildContext 
context) 
{
 
 
 
 
return 
Stack(
 
 
 
 
 
 
// 
Aligment 
的取值範圍為 
[-1, 
1],Stack 
中心為 
(0, 
0),

 
 
 
 
 
 
// 
這裡設定為 
(-0.5, 
-0.5) 
後,可以讓文字對齊到 
Container 
的 
1/4 

 
 
 
 
 
 
alignment: 
const 
Alignment(-0.5
-0.5),
 
 
 
 
 
 
children: 
<
Widget>
[
 
 
 
 
 
 
 
 
Container(
 
 
 
 
 
 
 
 
 
 
width: 
200.0,
 
 
 
 
 
 
 
 
 
 
height: 
200.0,
 
 
 
 
 
 
 
 
 
 
color: 
Colors.blue,
 
 
 
 
 
 
 
 
),
 
 
 
 
 
 
 
 
Text('foobar'),
 
 
 
 
 
 
],
 
 
 
 
);

 
 

}

}
複製程式碼

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>screenshot-stack margin: 0px;
padding: 0px;
margin-top: 10px;
text-align: center;
color: rgb(153, 153, 153);
font-size: 0.7em;
“>screenshot-stack

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>示例一

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>lakes-diagram margin: 0px;
padding: 0px;
margin-top: 10px;
text-align: center;
color: rgb(153, 153, 153);
font-size: 0.7em;
“>lakes-diagram

color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
“>展示圖片
    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    margin-bottom: 0.5em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    margin-bottom: 0.5em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">flutter:

     
     

    The 
    following 
    line 
    ensures 
    that 
    the 
    Material 
    Icons 
    font 
    is

     
     

    included 
    with 
    your 
    application, 
    so 
    that 
    you 
    can 
    use 
    the 
    icons 
    in

     
     

    the 
    material 
    Icons 
    class.

     
     
    uses-material-design: 
    true

     
     

    To 
    add 
    assets 
    to 
    your 
    application, 
    add 
    an 
    assets 
    section, 
    like 
    this:

     
     

    assets:

     
     

     

    images/a_dot_burr.jpeg

     
     

     

    images/a_dot_ham.jpeg

    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">flutter:

     
     

    The 
    following 
    line 
    ensures 
    that 
    the 
    Material 
    Icons 
    font 
    is

     
     

    included 
    with 
    your 
    application, 
    so 
    that 
    you 
    can 
    use 
    the 
    icons 
    in

     
     

    the 
    material 
    Icons 
    class.

     
     
    uses-material-design: 
    true

     
     

    To 
    add 
    assets 
    to 
    your 
    application, 
    add 
    an 
    assets 
    section, 
    like 
    this:

     
     
    assets:
     
     
     
     

    images/lake.jpg
    複製程式碼

  1. color: inherit;
    line-height: inherit;
    padding: 0px;
    margin: 1.5em 0px;
    margin-top: 0px;
    “>現在,我們可以把這張圖片展示出來了:
    void 
    main() 
    {
     
     
    runApp(MyApp());


    }

    class 
    MyApp 
    extends 
    StatelessWidget 
    {
     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    return 
    MaterialApp(
     
     
     
     
     
     
    title: 
    'Flutter 
    UI 
    basic 
    1'
    ,
     
     
     
     
     
     
    home: 
    Scaffold(
     
     
     
     
     
     
     
     
    appBar: 
    AppBar(
     
     
     
     
     
     
     
     
     
     
    title: 
    Text('Top 
    Lakes'
    ),
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
    body: 
    Image.asset(
     
     
     
     
     
     
     
     
     
     
    'images/lake.jpg',
     
     
     
     
     
     
     
     
     
     
    width: 
    600.0,
     
     
     
     
     
     
     
     
     
     
    height: 
    240.0,
     
     
     
     
     
     
     
     
     
     
    // 
    cover 
    類似於 
    Android 
    開發中的 
    centerCrop,其他一些型別,讀者可以檢視

     
     
     
     
     
     
     
     
     
     
    // 
    https://docs.flutter.io/flutter/painting/BoxFit-class.html

     
     
     
     
     
     
     
     
     
     
    fit: 
    BoxFit.cover,
     
     
     
     
     
     
     
     
    )
     
     
     
     
     
     
    ),
     
     
     
     
    );

     
     

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    font-weight: bold;
    “>強烈建議在遇到不熟悉的 API 時翻一翻文件,並在文件中找到 demo 所使用的 API。我們的例子不可能覆蓋所有的 API,通過這種方式熟悉文件後,讀者就可以根據文件實現出自己想要的效果。不妨就從 Image 開始吧,在 color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “>佈局

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “> margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">class 
    _TitleSection 
    extends 
    StatelessWidget 
    {
     
     
    final 
    String 
    title;

     
     
    final 
    String 
    subtitle;

     
     
    final 
    int 
    starCount;


     
     
    _TitleSection(this.title, 
    this.subtitle, 
    this.starCount);


     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    // 
    為了給 
    title 
    section 
    加上 
    padding,這裡我們給內容套一個 
    Container

     
     
     
     
    return 
    Container(
     
     
     
     
     
     
    // 
    設定上下左右的 
    padding 
    都是 
    32。類似的還有 
    EdgeInsets.only/symmetric 

     
     
     
     
     
     
    padding: 
    EdgeInsets.all(32.0),
     
     
     
     
     
     
    child: 
    Row(
     
     
     
     
     
     
     
     
    children: 
    <
    Widget>
    [
     
     
     
     
     
     
     
     
     
     
    // 
    這裡為了讓標題佔滿螢幕寬度的剩餘空間,用 
    Expanded 
    把標題包了起來

     
     
     
     
     
     
     
     
     
     
    Expanded(
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    再次提醒讀者,Expanded 
    只能包含一個子元素,使用的引數名是 
    child。接下來,

     
     
     
     
     
     
     
     
     
     
     
     
    // 
    為了在豎直方向放兩個標題,加入一個 
    Column。

     
     
     
     
     
     
     
     
     
     
     
     
    child: 
    Column(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    Column 
    是豎直方向的,cross 
    為交叉的意思,也就是說,這裡設定的是水平方向

     
     
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    的對齊。在水平方向,我們讓文字對齊到 
    start(讀者可以修改為 
    end 
    看看效果)

     
     
     
     
     
     
     
     
     
     
     
     
     
     
    crossAxisAlignment: 
    CrossAxisAlignment.start,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    children: 
    <
    Widget>
    [
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    聰明的你,這個時候肯定知道為什麼突然加入一個 
    Container 
    了。

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    跟前面一樣,只是為了設定一個 
    padding

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Container(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    padding: 
    const 
    EdgeInsets.only(bottom: 
    8.0),
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    child: 
    Text(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    title,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    style: 
    TextStyle(fontWeight: 
    FontWeight.bold),
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Text(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    subtitle,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    style: 
    TextStyle(color: 
    Colors.grey[500]),
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    )
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    ],
     
     
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
     
     
    ),

     
     
     
     
     
     
     
     
     
     
    // 
    這裡是 
    Row 
    的第二個子元素,下面這兩個就沒用太多值得說的東西了。

     
     
     
     
     
     
     
     
     
     
    Icon(
     
     
     
     
     
     
     
     
     
     
     
     
    Icons.star,
     
     
     
     
     
     
     
     
     
     
     
     
    color: 
    Colors.red[500],
     
     
     
     
     
     
     
     
     
     
    ),

     
     
     
     
     
     
     
     
     
     
    Text(starCount.toString())
     
     
     
     
     
     
     
     
    ],
     
     
     
     
     
     
    ),
     
     
     
     
    );

     
     

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “>對齊

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “> margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">Widget 
    _buildButtonColumn(BuildContext 
    context, 
    IconData 
    icon, 
    String 
    label) 
    {
     
     
    final 
    color 

    Theme.of(context).primaryColor;


     
     
    return 
    Column(
     
     
     
     
    // 
    main 
    axis 
    跟我們前面提到的 
    cross 
    axis 
    相對應,對 
    Column 
    來說,指的就是豎直方向。

     
     
     
     
    // 
    在放置完子控制元件後,螢幕上可能還會有一些剩餘的空間(free 
    space),min 
    表示儘量少佔用

     
     
     
     
    // 
    free 
    space;類似於 
    Android 
    的 
    wrap_content。

     
     
     
     
    // 
    對應的,還有 
    MainAxisSize.max

     
     
     
     
    mainAxisSize: 
    MainAxisSize.min,
     
     
     
     
    // 
    沿著 
    main 
    axis 
    居中放置

     
     
     
     
    mainAxisAlignment: 
    MainAxisAlignment.center,

     
     
     
     
    children: 
    <
    Widget>
    [
     
     
     
     
     
     
    Icon(icon, 
    color: 
    color),
     
     
     
     
     
     
    Container(
     
     
     
     
     
     
     
     
    margin: 
    const 
    EdgeInsets.only(top: 
    8.0),
     
     
     
     
     
     
     
     
    child: 
    Text(
     
     
     
     
     
     
     
     
     
     
    label,
     
     
     
     
     
     
     
     
     
     
    style: 
    TextStyle(
     
     
     
     
     
     
     
     
     
     
     
     
    fontSize: 
    12.0,
     
     
     
     
     
     
     
     
     
     
     
     
    fontWeight: 
    FontWeight.w400,
     
     
     
     
     
     
     
     
     
     
     
     
    color: 
    color,
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
    )
     
     
     
     
    ],
     
     
    );


    }

    class 
    MyApp 
    extends 
    StatelessWidget 
    {
     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    //...

     
     
     
     
    Widget 
    buttonSection 

    Container(
     
     
     
     
     
     
    child: 
    Row(
     
     
     
     
     
     
     
     
    // 
    沿水平方向平均放置

     
     
     
     
     
     
     
     
    mainAxisAlignment: 
    MainAxisAlignment.spaceEvenly,
     
     
     
     
     
     
     
     
    children: 
    [
     
     
     
     
     
     
     
     
     
     
    _buildButtonColumn(context, 
    Icons.call, 
    'CALL'),
     
     
     
     
     
     
     
     
     
     
    _buildButtonColumn(context, 
    Icons.near_me, 
    'ROUTE'),
     
     
     
     
     
     
     
     
     
     
    _buildButtonColumn(context, 
    Icons.share, 
    'SHARE'),
     
     
     
     
     
     
     
     
    ],
     
     
     
     
     
     
    ),
     
     
     
     
    );

     
     
    //...

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “> margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “>全部放到一起
    class 
    MyApp 
    extends 
    StatelessWidget 
    {
     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    final 
    titleSection 

    _TitleSection(
     
     
     
     
     
     
     
     
    'Oeschinen 
    Lake 
    Campground'

    'Kandersteg, 
    Switzerland'

    41);

     
     
     
     
    final 
    buttonSection 

    ...;

     
     
     
     
    final 
    textSection 

    Container(
     
     
     
     
     
     
     
     
    padding: 
    const 
    EdgeInsets.all(32.0),
     
     
     
     
     
     
     
     
    child: 
    Text(
     
     
     
     
     
     
     
     
     
     
    '''
    Lake 
    Oeschinen 
    lies 
    at 
    the 
    foot 
    of 
    the 
    Blüemlisalp 
    in 
    the 
    Bernese 
    Alps. 
    Situated 
    1,578 
    meters 
    above 
    sea 
    level, 
    it 
    is 
    one 
    of 
    the 
    larger 
    Alpine 
    Lakes. 

    gondola 
    ride 
    from 
    Kandersteg, 
    followed 
    by 

    half-hour 
    walk 
    through 
    pastures 
    and 
    pine 
    forest, 
    leads 
    you 
    to 
    the 
    lake, 
    which 
    warms 
    to 
    20 
    degrees 
    Celsius 
    in 
    the 
    summer. 
    Activities 
    enjoyed 
    here 
    include 
    rowing, 
    and 
    riding 
    the 
    summer 
    toboggan 
    run.
     
     
     
     
     
     
     
     
     
     
    '''
    ,
     
     
     
     
     
     
     
     
     
     
    softWrap: 
    true,
     
     
     
     
     
     
     
     
    ),
     
     
     
     
    );


     
     
     
     
    return 
    MaterialApp(
     
     
     
     
     
     
    title: 
    'Flutter 
    UI 
    basic 
    1'
    ,
     
     
     
     
     
     
    home: 
    Scaffold(
     
     
     
     
     
     
     
     
     
     
    appBar: 
    AppBar(
     
     
     
     
     
     
     
     
     
     
     
     
    title: 
    Text('Top 
    Lakes'
    ),
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
     
     
    // 
    由於我們的內容可能會超出螢幕的長度,這裡把內容都放到 
    ListView 
    裡。

     
     
     
     
     
     
     
     
     
     
    // 
    除了這種用法,ListView 
    也可以像我們在 
    Android 
    原生開發中使用 
    ListView 
    那樣,

     
     
     
     
     
     
     
     
     
     
    // 
    根據資料動態生成一個個 
    item。這個我們在下一節再來學習

     
     
     
     
     
     
     
     
     
     
    body: 
    ListView(
     
     
     
     
     
     
     
     
     
     
     
     
    children: 
    <
    Widget>
    [
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Image.asset(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    'images/lake.jpg',
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    width: 
    600.0,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    height: 
    240.0,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    cover 
    類似於 
    Android 
    開發中的 
    centerCrop,其他一些型別,讀者可以檢視

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    // 
    https://docs.flutter.io/flutter/painting/BoxFit-class.html

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    fit: 
    BoxFit.cover,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    ),

     
     
     
     
     
     
     
     
     
     
     
     
     
     
    titleSection,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    buttonSection,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    textSection
     
     
     
     
     
     
     
     
     
     
     
     
    ],
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
    )
     
     
     
     
    );

     
     

    }

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “> margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">git 
    clone 
    https://github.com/Jekton/flutter_demo.git
    cd 
    flutter_demo
    git 
    checkout 
    ui-basic1
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “>示例二

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “> margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    color: inherit;
    line-height: inherit;
    padding: 0px;
    margin: 1.5em 0px;
    “>首先給資料建模:
    enum 
    BuildingType 

    theater, 
    restaurant 

    }

    class 
    Building 
    {
     
     
    final 
    BuildingType 
    type;

     
     
    final 
    String 
    title;

     
     
    final 
    String 
    address;


     
     
    Building(this.type, 
    this.title, 
    this.address);


    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">class 
    ItemView 
    extends 
    StatelessWidget 
    {
     
     
    final 
    int 
    position;

     
     
    final 
    Building 
    building;


     
     
    ItemView(this.position, 
    this.building);


     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    final 
    icon 

    Icon(
     
     
     
     
     
     
     
     
    building.type 
    == 
    BuildingType.restaurant
     
     
     
     
     
     
     
     
     
     
     
     

    Icons.restaurant
     
     
     
     
     
     
     
     
     
     
     
     

    Icons.theaters,
     
     
     
     
     
     
     
     
    color: 
    Colors.blue[500]);


     
     
     
     
    final 
    widget 

    Row(
     
     
     
     
     
     
    children: 
    <
    Widget>
    [
     
     
     
     
     
     
     
     
    Container(
     
     
     
     
     
     
     
     
     
     
    margin: 
    EdgeInsets.all(16.0),
     
     
     
     
     
     
     
     
     
     
    child: 
    icon,
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
    Expanded(
     
     
     
     
     
     
     
     
     
     
    child: 
    Column(
     
     
     
     
     
     
     
     
     
     
     
     
    crossAxisAlignment: 
    CrossAxisAlignment.start,
     
     
     
     
     
     
     
     
     
     
     
     
    children: 
    <
    Widget>
    [
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Text(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    building.title,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    style: 
    TextStyle(
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    fontSize: 
    20.0,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    fontWeight: 
    FontWeight.w500,
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    )
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Text(building.address)
     
     
     
     
     
     
     
     
     
     
     
     
    ],
     
     
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
    )
     
     
     
     
     
     
    ],
     
     
     
     
    );


     
     
     
     
    return 
    widget;

     
     

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">class 
    BuildingListView 
    extends 
    StatelessWidget 
    {
     
     
    final 
    List<
    Building>
     
    buildings;


     
     
    BuildingListView(this.buildings);


     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    // 
    ListView.builder 
    可以按需生成子控制元件

     
     
     
     
    return 
    ListView.builder(
     
     
     
     
     
     
    itemCount: 
    buildings.length,
     
     
     
     
     
     
    itemBuilder: 
    (context, 
    index) 
    {
     
     
     
     
     
     
     
     
    return 
    new 
    ItemView(index, 
    buildings[index]);

     
     
     
     
     
     

    }
     
     
     
     
    );

     
     

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">// 
    定義一個回撥介面

    typedef 
    OnItemClickListener 

    void 
    Function(int 
    position);


    class 
    ItemView 
    extends 
    StatelessWidget 
    {

     
     
    final 
    int 
    position;

     
     
    final 
    Building 
    building;

     
     
    final 
    OnItemClickListener 
    listener;


     
     
    // 
    這裡的 
    listener 
    會從 
    ListView 
    那邊傳過來

     
     
    ItemView(this.position, 
    this.building, 
    this.listener);


     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    final 
    widget 

    ...;


     
     
     
     
    // 
    一般來說,為了監聽手勢事件,我們使用 
    GestureDetector。但這裡為了在點選的時候有個

     
     
     
     
    // 
    水波紋效果,使用的是 
    InkWell。

     
     
     
     
    return 
    InkWell(
     
     
     
     
     
     
    onTap: 
    () 
    =>
     
    listener(position),
     
     
     
     
     
     
    child: 
    widget
     
     
     
     
    );

     
     

    }

    }

    class 
    BuildingListView 
    extends 
    StatelessWidget 
    {
     
     
    final 
    List<
    Building>
     
    buildings;

     
     
    final 
    OnItemClickListener 
    listener;


     
     
    // 
    這是對外介面。外部通過建構函式傳入資料和 
    listener

     
     
    BuildingListView(this.buildings, 
    this.listener);


     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    return 
    ListView.builder(
     
     
     
     
     
     
    itemCount: 
    buildings.length,
     
     
     
     
     
     
    itemBuilder: 
    (context, 
    index) 
    {
     
     
     
     
     
     
     
     
    return 
    new 
    ItemView(index, 
    buildings[index], 
    listener);

     
     
     
     
     
     

    }
     
     
     
     
    );

     
     

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">void 
    main() 
    {
     
     
    runApp(MyApp());


    }

    class 
    MyApp 
    extends 
    StatelessWidget 
    {

     
     
    @override
     
     
    Widget 
    build(BuildContext 
    context) 
    {
     
     
     
     
    final 
    buildings 

    [
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'CineArts 
    at 
    the 
    Empire'

    '85 

    Portal 
    Ave'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'The 
    Castro 
    Theater'

    '429 
    Castro 
    St'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'Alamo 
    Drafthouse 
    Cinema'

    '2550 
    Mission 
    St'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'Roxie 
    Theater'

    '3117 
    16th 
    St'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'United 
    Artists 
    Stonestown 
    Twin'

    '501 
    Buckingham 
    Way'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'AMC 
    Metreon 
    16'

    '135 
    4th 
    St 
    #3000'
    ),
     
     
     
     
     
     
    Building(BuildingType.restaurant, 
    'K\'s 
    Kitchen'

    '1923 
    Ocean 
    Ave'
    ),
     
     
     
     
     
     
    Building(BuildingType.restaurant, 
    'Chaiya 
    Thai 
    Restaurant'

    '72 
    Claremont 
    Blvd'
    ),
     
     
     
     
     
     
    Building(BuildingType.restaurant, 
    'La 
    Ciccia'

    '291 
    30th 
    St'
    ),

     
     
     
     
     
     
    // 
    double 
    一下

     
     
     
     
     
     
    Building(BuildingType.theater, 
    'CineArts 
    at 
    the 
    Empire'

    '85 

    Portal 
    Ave'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'The 
    Castro 
    Theater'

    '429 
    Castro 
    St'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'Alamo 
    Drafthouse 
    Cinema'

    '2550 
    Mission 
    St'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'Roxie 
    Theater'

    '3117 
    16th 
    St'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'United 
    Artists 
    Stonestown 
    Twin'

    '501 
    Buckingham 
    Way'
    ),
     
     
     
     
     
     
    Building(BuildingType.theater, 
    'AMC 
    Metreon 
    16'

    '135 
    4th 
    St 
    #3000'
    ),
     
     
     
     
     
     
    Building(BuildingType.restaurant, 
    'K\'s 
    Kitchen'

    '1923 
    Ocean 
    Ave'
    ),
     
     
     
     
     
     
    Building(BuildingType.restaurant, 
    'Chaiya 
    Thai 
    Restaurant'

    '72 
    Claremont 
    Blvd'
    ),
     
     
     
     
     
     
    Building(BuildingType.restaurant, 
    'La 
    Ciccia'

    '291 
    30th 
    St'
    ),
     
     
     
     
    ];

     
     
     
     
    return 
    MaterialApp(
     
     
     
     
     
     
    title: 
    'ListView 
    demo'
    ,
     
     
     
     
     
     
    home: 
    Scaffold(
     
     
     
     
     
     
     
     
    appBar: 
    AppBar(
     
     
     
     
     
     
     
     
     
     
    title: 
    Text('Buildings'),
     
     
     
     
     
     
     
     
    ),
     
     
     
     
     
     
     
     
    body: 
    BuildingListView(buildings, 
    (index) 
    =>
     
    debugPrint('item 
    $index 
    clicked'
    ))
     
     
     
     
     
     
    ),
     
     
     
     
    );

     
     

    }

    }
    複製程式碼

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    “> margin: 0px;
    padding: 0px;
    margin-top: 10px;
    text-align: center;
    color: rgb(153, 153, 153);
    font-size: 0.7em;
    “>

    color: inherit;
    line-height: inherit;
    margin: 0px;
    padding: 0px;
    ">git 
    clone 
    https://github.com/Jekton/flutter_demo.git
    cd 
    flutter_demo
    git 
    checkout 
    ui-basic2
    複製程式碼

    推薦閱讀

    Flutter學習指南:熟悉Dart語言
    Flutter學習指南:編寫第一個應用
    Flutter學習指南:開發環境搭建

    color: inherit;
    line-height: inherit;
    padding: 0px;
    margin: 1.5em 0px;
    “>Flutter學習指南:UI佈局和控制元件https://juejin.im/post/5bd54b7be51d456c430e35f6
  2. 相關文章