在開發中我們的基礎控件大部分在容器類 Widget
中顯示,所以先來了Flutter
有哪些容器類Widget
這篇文章可能會有點亂,大概瞭解一下容器類 Widget 就行,知道哪些 容器 widget 可以實現哪些功能,使用的使用翻文檔即可
Container
Container 是最常用的容器類widget,下面是Container的定義:
Container({
this.alignment,
this.padding, //容器內補白,屬於decoration的裝飾範圍
Color color, // 背景色
Decoration decoration, // 背景裝飾
Decoration foregroundDecoration, //前景裝飾
double width,//容器的寬度
double height, //容器的高度
BoxConstraints constraints, //容器大小的限制條件
this.margin,//容器外補白,不屬於decoration的裝飾範圍
this.transform, //變換
this.child,
})
實現上面圖片的這個例子的僞代碼如下:
Container(
margin: EdgeInsets.only(top: 50.0, left: 120.0), //容器外補白
constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0), //卡片大小
decoration: BoxDecoration(//背景裝飾
gradient: RadialGradient( //背景徑向漸變
colors: [Colors.red, Colors.orange],
center: Alignment.topLeft,
radius: .98
),
boxShadow: [ //卡片陰影
BoxShadow(
color: Colors.black54,
offset: Offset(2.0, 2.0),
blurRadius: 4.0
)
]
),
transform: Matrix4.rotationZ(.2), //卡片傾斜變換
alignment: Alignment.center, //卡片內文字居中
child: Text( //卡片文字
"5.20", style: TextStyle(color: Colors.white, fontSize: 40.0),
),
);
Scaffold、TabBar、底部導航
Scaffold
Flutter Material
庫提供了一個Scaffold Widget
,它是一個路由頁的骨架,可以非常容易的拼裝出一個完整的頁面。
上面兩圖中包含的內容:
- 一個導航欄
- 導航欄右邊有一個分享按鈕
- 有一個抽屜菜單
- 有一個底部導航
- 右下角有一個懸浮的動作按鈕
實現的僞代碼如下:
class ScaffoldRoute extends StatefulWidget {
@override
_ScaffoldRouteState createState() => _ScaffoldRouteState();
}
class _ScaffoldRouteState extends State<ScaffoldRoute> {
int _selectedIndex = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar( //導航欄
title: Text("App Name"),
actions: <Widget>[ //導航欄右側菜單
IconButton(icon: Icon(Icons.share), onPressed: () {}),
],
),
drawer: new MyDrawer(), //抽屜
bottomNavigationBar: BottomNavigationBar( // 底部導航
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.business), title: Text('Business')),
BottomNavigationBarItem(icon: Icon(Icons.school), title: Text('School')),
],
currentIndex: _selectedIndex,
fixedColor: Colors.blue,
onTap: _onItemTapped,
),
floatingActionButton: FloatingActionButton( //懸浮按鈕
child: Icon(Icons.add),
onPressed:_onAdd
),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
void _onAdd(){
}
}
Appar
AppBar是一個Material風格的導航欄,它可以設置標題、導航欄菜單、底部Tab等
AppBar({
Key key,
this.leading, //導航欄最左側Widget,常見爲抽屜菜單按鈕或返回按鈕。
this.automaticallyImplyLeading = true, //如果leading爲null,是否自動實現默認的leading按鈕
this.title,// 頁面標題
this.actions, // 導航欄右側菜單
this.bottom, // 導航欄底部菜單,通常爲Tab按鈕組
this.elevation = 4.0, // 導航欄陰影
this.centerTitle, //標題是否居中
this.backgroundColor,
... //其它屬性見源碼註釋
})
TabBar
Material組件庫中提供了一個TabBar組件,它可以快速生成Tab菜單
底部導航
可以通過Scaffold的bottomNavigationBar屬性來設置底部導航
具體實現參考:https://book.flutterchina.club/chapter5/material_scaffold.html
BoxConstraints和SizedBox
BoxConstraints
用於對齊子widget
添加額外的約束。
const BoxConstraints({
this.minWidth = 0.0, //最小寬度
this.maxWidth = double.infinity, //最大寬度
this.minHeight = 0.0, //最小高度
this.maxHeight = double.infinity //最大高度
})
SizedBox 用於給子widget指定固定的寬高,如:
SizedBox(
width: 80.0,
height: 80.0,
child: redBox
)
DecoratedBox
DecoratedBox可以在其子widget繪製前(或後)繪製一個裝飾Decoration(如背景、邊框、漸變等)
DecoratedBox定義如下:
const DecoratedBox({
Decoration decoration,
DecorationPosition position = DecorationPosition.background,
Widget child
})
- decoration:代表將要繪製的裝飾,它類型爲Decoration,Decoration是一個抽象類,它定義了一個接口 createBoxPainter(),子類的主要職責是需要通過實現它來創建一個畫筆,該畫筆用於繪製裝飾。
- position:此屬性決定在哪裏繪製Decoration,它接收DecorationPosition的枚舉類型,該枚舉類兩個值:
- background:在子widget之後繪製,即背景裝飾。
- foreground:在子widget之上繪製,即前景。
BoxDecoration
它是一個Decoration的子類,實現了常用的裝飾元素的繪製
BoxDecoration({
Color color, //顏色
DecorationImage image,//圖片
BoxBorder border, //邊框
BorderRadiusGeometry borderRadius, //圓角
List<BoxShadow> boxShadow, //陰影,可以指定多個
Gradient gradient, //漸變
BlendMode backgroundBlendMode, //背景混合模式
BoxShape shape = BoxShape.rectangle, //形狀
})
該效果實現如下:
DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(colors:[Colors.red,Colors.orange[700]]), //背景漸變
borderRadius: BorderRadius.circular(3.0), //3像素圓角
boxShadow: [ //陰影
BoxShadow(
color:Colors.black54,
offset: Offset(2.0,2.0),
blurRadius: 4.0
)
]
),
child: Padding(padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
child: Text("Login", style: TextStyle(color: Colors.white),),
)
)