- Widget樹(shù)是我們創(chuàng)建UI的方式,在Flutter中我們經(jīng)??吹交蚵?tīng)到這樣一句話(huà):一切皆Widget,Widget地獄嵌套。為了代碼更容易理解:盡可能的保持Widget樹(shù)層級(jí)較淺。
Material Design:Widget樹(shù)的屬性
Scaffold:腳手架,實(shí)現(xiàn)Material可視化布局
AppBar:界面頂部實(shí)現(xiàn)工具欄
CircleAvatar:顯示一張圓形用戶(hù)資料照片,可用于任何圖片
Divider:繪制一條具有上下邊距的水平線(xiàn)
SingleChildScrollView:可將垂直或水平滾動(dòng)能力增加到單個(gè)子Widget上,防止屏幕溢出,內(nèi)容過(guò)多時(shí)不建議使用,影響性能
Padding:可添加上、下、左、右內(nèi)邊距
Column:顯示子Widget縱向列表
Row:顯示子Widget橫向列表
Container:可用于空白占位符(不可見(jiàn)),也可設(shè)置其它屬性靈活運(yùn)用
Expanded:可填充從屬于Column或Row Widget的子Widget可用空間
Text:界面顯示的文本
Stack:層疊組件、絕對(duì)定位
Positioned:允許設(shè)置寬高,與Stack結(jié)合使用,指定Stack Widget上、下、左、右四邊的定位距離
//引入Material風(fēng)格庫(kù),使用Material風(fēng)格組件
import 'package:flutter/material.dart';
//創(chuàng)建有狀態(tài)Widget
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
//創(chuàng)建變量,初始值0
int _counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Widget Tree'),
),
body: SafeArea(//SafeArea適配屏幕安全區(qū)
child: SingleChildScrollView(//防止Widget屏幕滾動(dòng)溢出
child: Padding(//內(nèi)邊距
padding: EdgeInsets.all(16.0),//上下左右邊距16
child: Column(//縱向列表,可放置多個(gè)子Widget
children: <Widget>[
const RowWidget(),//Widget
Padding(
padding: EdgeInsets.all(16.0),
),
const RowAndColumnWidget(),//Widget
CounterTextWidget(counter: _counter),//Widget
TextButton(//按扭
child: Text('Add to Counter'),
//點(diǎn)擊事件宣染界面變化值
onPressed: () {
setState(() {
//回調(diào)方法
_addToCounter();
});
},
),
],
),
),
),
),
);
}
//自定義方法函數(shù)
void _addToCounter() {
return setState(() {
_counter++;
});
}
}
//構(gòu)建自定義類(lèi)Widget
class CounterTextWidget extends StatelessWidget {
//使用const關(guān)鍵字得到緩存性能優(yōu)勢(shì)
const CounterTextWidget({
Key key,
@required int counter,
}) : _counter = counter,
super(key: key);
final int _counter;
@override
Widget build(BuildContext context) {
print('CounterTextWidget $_counter');
return Text('CounterTextWidget $_counter');
}
}
//構(gòu)建類(lèi)Widget
class RowWidget extends StatelessWidget {
const RowWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
print('RowWidget');
return Row(
children: <Widget>[
Container(
color: Colors.yellow,
height: 40.0,
width: 40.0,
),
Padding(
padding: EdgeInsets.all(16.0),
),
Expanded(
child: Container(
color: Colors.amber,
height: 40.0,
width: 40.0,
),
),
Padding(
padding: EdgeInsets.all(16.0),
),
Container(
color: Colors.brown,
height: 40.0,
width: 40.0,
),
],
);
}
}
//構(gòu)建類(lèi)Widget
class RowAndColumnWidget extends StatelessWidget {
const RowAndColumnWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
print('RowAndColumnWidget');
return Row(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
color: Colors.yellow,
height: 60.0,
width: 60.0,
),
Padding(
padding: EdgeInsets.all(16.0),
),
Container(
color: Colors.amber,
height: 40.0,
width: 40.0,
),
Padding(
padding: EdgeInsets.all(16.0),
),
Container(
color: Colors.brown,
height: 20.0,
width: 20.0,
),
Divider(),
//調(diào)用RowAndStackWidget
const RowAndStackWidget(),
Divider(),
Text('End of the Line. Date: ${DateTime.now()}'),
],
),
],
);
}
}
//構(gòu)建類(lèi)Widget
class RowAndStackWidget extends StatelessWidget {
const RowAndStackWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
print('RowAndStackWidget');
return Row(
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.lightGreen,
radius: 100.0,
child: Stack(
children: <Widget>[
Container(
height: 100.0,
width: 100.0,
color: Colors.yellow,
),
Container(
height: 60.0,
width: 60.0,
color: Colors.amber,
),
Container(
height: 40.0,
width: 40.0,
color: Colors.brown,
),
],
),
),
],
);
}
}
- 以上代碼使用了類(lèi)Widget提高代碼理解可閱讀性
- 除了用類(lèi)構(gòu)建Widget還可以用常量與方法函數(shù)構(gòu)建Widget,注意在使用常量初始化時(shí)Widget會(huì)依賴(lài)父Widget的BuildContext對(duì)象,每次重繪父Widget,常量也會(huì)重繪,因此無(wú)進(jìn)行性能優(yōu)化,所以不推薦使用,方法函數(shù)Widget同理,下面我看一下常量widget與方法函數(shù)Widget的寫(xiě)法:
//常量Widget
final container = Container(
color:Colors.Blue,
height:40,
width:40);
//方法Widget
Widget _buildContainer(){
return Container(
color:Colors.Blue,
height:40,
width:40,
);
}