目錄
- Padding(間距)
- ConstrainedBox(約束盒)
- SizeBox(固定盒)
- UnconstrainedBox(無約束盒)
- DecoratedBox(裝飾盒)
- Container(組合容器)
- Scaffold Widget and TabBar Widget(腳手架及切換組件)
Padding(間距)
使用 padding 標(biāo)簽可以給子 widget 添加間距
const Padding({
Key key,
@required this.padding,
Widget child,
}) : assert(padding != null),
super(key: key, child: child);
- all:指定四個方向使用同一間距
- fromLTRB:四個方向間距分別制定
- only:指定單一具體方向間距
- symmetric:設(shè)置對稱方向間距(vertical = top+bottom,horizontal = left+right)
/**
* @des Padding Widget
* @author liyongli 20190424
* */
class PaddingWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _PaddingState();
}
/**
* @des Padding Widget State
* @author liyongli 20190424
* */
class _PaddingState extends State<PaddingWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Padding Widget"),
),
body: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: RaisedButton(
child: Text("四個方向間距統(tǒng)一"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
Padding(
padding: EdgeInsets.fromLTRB(0.0,20.0,40.0,20.0),
child: RaisedButton(
child: Text("分別指定四個方向"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
Padding(
padding: EdgeInsets.only(left:40.0),
child: RaisedButton(
child: Text("單一方向添加邊距"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 20.0),
child: RaisedButton(
child: Text("對稱方向添加邊距"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
],
)
),
);
}
// 按鈕點擊監(jiān)聽
void _BtnClick(){
print("不設(shè)置點擊事件按鈕會是灰色的!");
}
}

ConstrainedBox(約束盒)
constrainedBox 可以給子 widget 添加更多約束條件。與 sizedBox 同通過 renderConstrainedBox 繪制
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity
});
- minWidth:子 widget 最小寬度
- maxWidth:子 widget 最大寬度
- minHeight:子 widget 最小高度
- maxHeight:子 widget 最大高度
@override
RenderConstrainedBox createRenderObject(BuildContext context) {
return new RenderConstrainedBox(
additionalConstraints: ...,
);
}
/**
* @des ConstrainedBox Widget
* @author liyongli 20190424
* */
class ConstrainedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ConstrainedBoxState();
}
/**
* @des ConstrainedBox Widget State
* @author liyongli 20190424
* */
class _ConstrainedBoxState extends State<ConstrainedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("ConstrainedBox Widget"),
),
body: ConstrainedBox(
constraints: BoxConstraints(
minHeight: 50.0,
minWidth: double.infinity
),
child: RaisedButton(
child: Text("A"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
)
),
)
);
}
// 按鈕點擊監(jiān)聽
void _BtnClick(){
print("不設(shè)置點擊事件按鈕會是灰色的!");
}
}

SizeBox(固定盒)
sizedBox 可以給子 widget 指定寬高。與 constrainedBox 同通過 renderConstrainedBox 繪制
@override
RenderConstrainedBox createRenderObject(BuildContext context) {
return new RenderConstrainedBox(
additionalConstraints: ...,
);
}
/**
* @des SizedBox Widget
* @author liyongli 20190424
* */
class SizedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _SizedBoxState();
}
/**
* @des SizedBox Widget State
* @author liyongli 20190424
* */
class _SizedBoxState extends State<SizedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("SizedBox Widget"),
),
body: SizedBox(
width: double.infinity,
height: 80.0,
child: RaisedButton(
child: Text("A"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
)
),
)
);
}
// 按鈕點擊監(jiān)聽
void _BtnClick(){
print("不設(shè)置點擊事件按鈕會是灰色的!");
}
}

UnconstrainedBox(無約束盒)
unconstrainedBox 允許子 widget 按照自有屬性繪制,可用作去除父 widget 限制
/**
* @des UnconstrainedBox Widget
* @author liyongli 20190424
* */
class UnconstrainedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _UnconstrainedBoxState();
}
/**
* @des UnconstrainedBox Widget State
* @author liyongli 20190424
* */
class _UnconstrainedBoxState extends State<UnconstrainedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("UnconstrainedBox Widget"),
),
body: SizedBox(
width: double.infinity,
height: 80.0,
child: UnconstrainedBox(
child: RaisedButton(
child: Text("A"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
)
),
)
);
}
// 按鈕點擊監(jiān)聽
void _BtnClick(){
print("不設(shè)置點擊事件按鈕會是灰色的!");
}
}

雖然從效果來看,父 widget 的限制沒有起作用,但是實際上它只是沒有影響子 widget 的大小,但還是占有了響應(yīng)的空間
DecoratedBox(裝飾盒)
decoratedBox 可以給子 widget 繪制前、后增添一個裝飾
const DecoratedBox({
Key key,
@required this.decoration,
this.position = DecorationPosition.background,
Widget child
}) : assert(decoration != null),
assert(position != null),
super(key: key, child: child);
- decoration:即將繪制的裝飾
- position:繪制時間。background = 在子 widget 之后繪制,foreground = 在子 widget 之前繪制
- child:子 widget
/**
* @des DecoratedBox Widget
* @author liyongli 20190425
* */
class DecoratedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _DecoratedBoxState();
}
/**
* @des DecoratedBox Widget State
* @author liyongli 20190425
* */
class _DecoratedBoxState extends State<DecoratedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("DecoratedBox Widget"),
),
body: DecoratedBox(
// 裝飾
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
gradient: LinearGradient(colors: [Colors.blue,Colors.purpleAccent]),
boxShadow: [
BoxShadow(
color: Colors.blue,
offset: Offset(5.0, 5.0),
blurRadius: 20.0
)
]
),
// 主體
child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.0,horizontal: 40.0),
child: Text("flutter", style: TextStyle(color: Colors.white ),),
),
),
)
);
}
}

Container(組合容器)
container 是各種我們已知的 widget 的組合,使用它可以實現(xiàn)裝飾、變換、限制等各種效果
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
),
decoration = decoration ?? (color != null ? BoxDecoration(color: color) : null),
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints,
super(key: key);
- width、height:當(dāng)一級標(biāo)簽與 constraints 中同時包含 width、height 時,一級標(biāo)簽優(yōu)先
/**
* @des Container Widget
* @author liyongli 20190425
* */
class ContainerWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ContainerState();
}
/**
* @des Container Widget State
* @author liyongli 20190425
* */
class _ContainerState extends State<ContainerWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Container Widget"),
),
body: Container(
margin: EdgeInsets.only(left:70.0), //容器外間距
constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0), //卡片大小
// 裝飾
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
gradient: LinearGradient(colors: [Colors.blue,Colors.purpleAccent]),
boxShadow: [
BoxShadow(
color: Colors.blue,
offset: Offset(5.0, 5.0),
blurRadius: 20.0
)
]
),
transform: Matrix4.rotationZ(0.2), //卡片傾斜變換
alignment: Alignment.center, //卡片內(nèi)文字居中
child: Text("flutter", style: TextStyle(color: Colors.white ),),
)
)
);
}
}

Scaffold Widget and TabBar Widget(腳手架及切換組件)
scaffold 是 Materrial 庫中提供的一個腳手架,可以幫助開發(fā)者更快的完成功能頁的開發(fā)
const Scaffold({
Key key,
this.appBar,
this.body,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.floatingActionButtonAnimator,
this.persistentFooterButtons,
this.drawer,
this.endDrawer,
this.bottomNavigationBar,
this.bottomSheet,
this.backgroundColor,
this.resizeToAvoidBottomPadding,
this.resizeToAvoidBottomInset,
this.primary = true,
this.drawerDragStartBehavior = DragStartBehavior.down,
}) : assert(primary != null),
assert(drawerDragStartBehavior != null),
super(key: key);
- key:當(dāng)前元素的唯一標(biāo)識符(類似于 Android 中的 id)
- appBar:頂部導(dǎo)航欄
- body:主體部分
- floatingActionButton:懸浮按鈕
- drawer:抽屜部件
- bottomNavigationBar:底部導(dǎo)航欄
模擬商品詳情頁骨架
/**
* @des Scaffold Widget
* @author liyongli 20190426
* */
class ScaffoldWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ScaffoldState();
}
/**
* @des Scaffold Widget State
* @author liyongli 20190426
* */
class _ScaffoldState extends State<ScaffoldWidget>{
@override
Widget build(BuildContext context) {
return Scaffold(
// 導(dǎo)航欄
appBar: AppBar( title: Text("Detail"),
centerTitle: true,
elevation: 3.0,
leading: Builder(builder: (context){
return IconButton(
iconSize: 20.0,
icon: Icon(Icons.arrow_back_ios, color: Colors.white,),
onPressed: _finishBtn,
);
}),
actions: <Widget>[
IconButton(
iconSize: 20.0,
icon: Icon(Icons.favorite_border, color: Colors.white,),
onPressed: _collectionBtn,
),
IconButton(
iconSize: 20.0,
icon: Icon(Icons.share, color: Colors.white,),
onPressed: _moreBtn,
),
],
),
// 懸浮按鈕
floatingActionButton: FloatingActionButton(
child: Icon(Icons.shopping_cart),
onPressed: _shoppingBtn,),
);
}
// finish
void _finishBtn(){
print("finish");
}
// shared
void _collectionBtn(){
print("shared");
}
// float
void _moreBtn(){
print("shared");
}
// shopping
void _shoppingBtn(){
print("shared");
}
}

模擬新聞類APP骨架
/**
* @des Scaffold and TabBar Widget
* @author liyongli 20190426
* */
class ScaffoldAndTabBarWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ScaffoldAndTabBarState();
}
/**
* @des Scaffold and TabBar Widget State
* @author liyongli 20190426
* */
class _ScaffoldAndTabBarState extends State<ScaffoldAndTabBarWidget>
with SingleTickerProviderStateMixin {
TabController _tabController;
List tabs = ["熱點","綜合","科技","教育","財經(jīng)"];
int _selectedIndex = 0;
@override
void initState() {
super.initState();
_tabController = new TabController(length: tabs.length, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
// 導(dǎo)航欄
appBar: AppBar(
title: Text("News Home", style: TextStyle(fontSize: 16.0),),
centerTitle: true,
elevation: 3.0,
leading: Builder(builder: (context){
return IconButton(
iconSize: 20.0,
icon: Icon(Icons.person, color: Colors.white,),
onPressed: _finishBtn,
);
}),
actions: <Widget>[
IconButton(
iconSize: 20.0,
icon: Icon(Icons.message, color: Colors.white,),
onPressed: _moreBtn,
),
],
bottom: TabBar( //生成Tab菜單
controller: _tabController,
tabs: tabs.map((e) => Tab(text: e)).toList()
),
),
bottomNavigationBar: BottomNavigationBar( // 底部導(dǎo)航
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.message), title: Text('Message')),
BottomNavigationBarItem(icon: Icon(Icons.person), title: Text('personal')),
],
currentIndex: _selectedIndex,
fixedColor: Colors.blue,
onTap: _onItemTapped,
),
body: TabBarView(
controller: _tabController,
children: tabs.map((e) { //創(chuàng)建3個Tab頁
return Container(
alignment: Alignment.center,
child: Text(e, textScaleFactor: 5),
);
}).toList(),
),
);
}
// finish
void _finishBtn(){
print("finish");
}
// shared
void _collectionBtn(){
print("shared");
}
// float
void _moreBtn(){
print("shared");
}
// shopping
void _shoppingBtn(){
print("shared");
}
void _onItemTapped(int index) {
}
}

本篇到此完結(jié),更多 Flutter 跨平臺移動端開發(fā) 原創(chuàng)內(nèi)容持續(xù)更新中~
期待您 關(guān)注 / 點贊 / 收藏 向著 大前端工程師 晉級!