級別:★☆☆☆☆
標籤:「Flutter 常用 Widget」「SafeArea」「Expanded」「Wrap」「FutureBuilder」
作者: ITWYW
審校: aTaller團隊
前言
筆者最近在看 Flutter Widget of the Week!,並落地了程式碼 FlutterLearningRecord。在本文中,筆者將分享幾個 Widget 的使用場景及使用方式。在本文中,筆者會介紹如下Widget:SafeArea、Expanded、Wrap、AnimatedContainer、Opacity、FutureBuilder、在底部AppBar居中的 FloatingActionButton。
首先給大家展示下目前筆者做的常用 Widget 的效果。
一、常用 Widget Demo 效果
筆者上方的常用 Widget Demo 效果圖,展示了SafeArea、Expanded、Wrap、AnimatedContainer、Opacity、FutureBuilder、在底部AppBar居中的 FloationgActionButton的使用場景及使用效果。
Widget | 使用場景 |
---|---|
SafeArea | 用於帶頭簾、下巴的裝置 |
Expanded | 用於Row、Column中的子Widget佈局完後,撐開剩餘空間 |
Wrap | 用於包裹可能子Widget可能越過螢幕邊界的場景,使子Widget可以換行 |
AnimatedContainer | 用於給子Widget做動畫效果 |
Opacity | 用於對子Widget做不透明度處理 |
AnimatedOpacity | 用於給子Widget的不透明度變化過程做動畫 |
FutureBuilder | 用於耗時任務,耗時執行完後返回請求到的資料 |
FloationActionButton | 可以在BottomAppBar底部居中,一定程度適用釋出視訊文章,也可在螢幕中其他位置懸浮 |
下邊給大家簡單介紹下上邊的Widget的使用方式。
二、常用 Widget 使用方式
1. SafeArea
1.1 不帶SafeArea 示意圖
1.2 帶SafeArea 示意圖
使用 SafeArea 作為 body 的子 Widget,原來的子 Widget 作為 SafeAreade 的子 Widget;
1.3 SafeArea 示例程式碼
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView(
children: <Widget>[
_randomColorContainer(),
],
),
),
);
}
複製程式碼
####2. Expanded
2.1 左右 Expanded(黃色部分Widget) 分別佔剩餘空間的2:1
Expanded 會顯然同級的其他 Widget 先佈局,之後剩餘的空間,Expanded 才會去佔用。
當有多個Expanded時,Expanded的 flex 引數,用於指定要佔空白的空間的比例。
2.2 Expaned 示例程式碼
Row _expandedRow3() {
return Row(
children: <Widget>[
Text(
'3.LeftText',
style: TextStyle(fontSize: 32.0, backgroundColor: Colors.greenAccent),
),
Expanded(
flex: 2,
child: Container(
height: 20.0,
color: Colors.yellow,
)),
Container(
color: Colors.blue,
width: 100.0,
// width: 10.0,
height: 50.0,
child: Text(
'C',
style:
TextStyle(fontSize: 32.0, backgroundColor: Colors.greenAccent),
),
),
Expanded(
flex: 1,
child: Container(
height: 20.0,
color: Colors.yellow,
)),
Container(
width: 100.0,
height: 50.0,
child: Text(
'Right',
style:
TextStyle(fontSize: 32.0, backgroundColor: Colors.greenAccent),
),
),
],
);
}
複製程式碼
####3. Wrap
3.1 Wrap Demo 示意圖
3.2 Wrap 示例程式碼
Wrap horizontalWrap(int index) {
return Wrap(
// 預設主軸為水平方向
// direction: Axis.horizontal,
children: <Widget>[
horizontalRandomColorWrapContainer(index++),
horizontalRandomColorWrapContainer(index++),
horizontalRandomColorWrapContainer(index++),
horizontalRandomColorWrapContainer(index++),
],
);
}
複製程式碼
####4. AnimatedContainer
4.1 AnimatedContainer 執行動畫前示意圖
4.2 AnimatedContainer 執行動畫後示意圖
AnimatedContainer 執行前後,改變了 Widget 的背景色、寬度、高度、子 Widget 的對齊方式。
AnimatedContainer 示例程式碼
AnimatedContainer(
onEnd: () {
print('動畫結束');
},
child: DecoratedBox(
child: FlutterLogo(size: halfContainerWH,),
decoration: BoxDecoration(
//TODO: borderRadius 效果
borderRadius: selected ? BorderRadius.all(Radius.circular(25.0)) : BorderRadius.all(Radius.circular(0)),
)),
duration: Duration(seconds: 2),
curve: Curves.linearToEaseOut,
width: selected ? halfContainerWH : containerWH,
height: selected ? containerWH : halfContainerWH,
alignment: selected ? Alignment.topCenter : Alignment.center,
color: selected ? Colors.purpleAccent : Colors.blueGrey),
複製程式碼
####5. Opacity
5.1 Opacity 的不透明度
5.2 Opacity 示例程式碼
Opacity(
opacity: 1.0,
child: Container(
decoration: BoxDecoration(color: Colors.blue),
child: Text(
'Opacity: 1.0',
style: TextStyle(
color: Colors.white,
backgroundColor: Colors.blue,
fontSize: 24.0),
),
),
// child: Text('Opacity:1.0'),
),
複製程式碼
6. AnimatedOpacity
6.1 AnimatedOpacity 改變透明度前
6.2 AnimatedOpacity 改變透明度後
6.3 AnimatedOpacity 示例程式碼
AnimatedOpacity(
onEnd: () {
print('動畫結束');
},
opacity: animatedOpacityValue,
duration: Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: FlutterLogo(size: 100.0),
),
複製程式碼
####7. FutureBuilder
7.1 FutureBuilder 效果圖
7.2 FutureBuilder 示例程式碼
FutureBuilder(
future: Dio().get('https://api.github.com/orgs/flutterchina/repos'),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Response response = snapshot.data;
// 請求結果有誤,顯示錯誤資訊
if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
// 顯示請求結果
return ListView(
children: response.data
.map<Widget>((obj) => ListTile(
title: Text(obj["name"]),
subtitle: Text(obj["full_name"])))
.toList(),
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
} else if (snapshot.connectionState == ConnectionState.none) {
}
// 請求過程中返回進度指示器
return CircularProgressIndicator(
strokeWidth: 10.0,
semanticsLabel: '請稍候...',
);
}),
複製程式碼
####8. FloationgActionButton
8.1 居中 FloatingActionButton 效果
8.2 floationActionButton 居中示例程式碼
floatingActionButton: FloatingActionButton(
// child: Text('FAB'),
child: Icon(Icons.add),
onPressed: () {
print('點選FAB');
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
color: Colors.blue,
child: Container(
height: 44.0,
),
),
複製程式碼
三、Demo
Demo 下載地址: FlutterLearningRecord
四、參考學習網址
- flutter.cn
- Building a web application with Flutter
- Flutter 文件
- Flutter 實戰免費線上PDF
- Flutter 核心原理
- 深入理解 Flutter 應用啟動
- Flutter原理:三棵重要的樹(渲染過程、佈局約束、應用檢視的構建等)
- 初識Flutter web
- 用Flutter 寫一個簡單頁面
筆者微信:可加並拉入《aTaller技術交流群》。
關注我們的途徑有:
aTaller(簡書)
aTaller(掘金)
aTaller(微信公眾號)
推薦文章:
Flutter 圖片載入
Flutter 混合棧複用原理
Flutter Platform Channel 使用與原始碼分析
Flutter Platform View 使用及原理簡析
奇舞週刊