常用 Widget 部件介紹及 Flutter 佈局方式
這是我參與11月更文挑戰的第2天,活動詳情檢視:2021最後一次更文挑戰
文字控制元件 Text
``` class TextDemo extends StatelessWidget { final TextStyle _textStyle = TextStyle( fontSize: 16.0, color: Colors.red, );
final String _lector = 'Flutter'; final String _title = 'Dark 語法詳解';
@override Widget build(BuildContext context) { return Text( '$_lector -- $_title:Flutter中文網是中國最大的Flutter開發者交流學習平臺,致力於打造Flutter開發中文社群。在這裡能輕鬆找到程式碼例項、專案案例、並有專人提供最新文件翻譯。', textAlign: TextAlign.center, style: _textStyle, maxLines: 3, overflow: TextOverflow.ellipsis, ); } } ```
TextStyle
: 為文字設定字號、顏色、字型樣式等。$變數
:可以通過$變數
的形式對字串進行拼接。textAlign
:設定文字居中還是居左或者居右。maxLines
:設定文字最大顯示行號。overflow
:顯示不完時文字的擷取方式。
可變文字控制元件 RichText
class RichTextDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RichText(
text: const TextSpan(
text: 'Flutter',
style: TextStyle(
fontSize: 30,
color: Colors.black,
),
children: [
TextSpan(
text: '中文網',
style: TextStyle(
fontSize: 16,
color: Colors.red,
),
),
TextSpan(
text: '是中國最大的Flutter開發者交流學習平臺',
style: TextStyle(
fontSize: 20,
color: Colors.blue,
),
),
]
),
);
}
}
RichText
中 text
是 TextSpan
型別,在 TextSpan
中可以新增 children
,children
是一個TextSpan
型別的 List
。我們可以在每個 TextSpan
中單獨設定要展示的文字及文字樣式 style
。最終展示的時候就是每個 TextSpan
中文字拼接起來的效果。可以做富文字展示。
Container
class ContainerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Row(
children: <Widget>[
Container(
color: Colors.yellow,
child: Icon(
Icons.add,
size: 45,
),
padding: EdgeInsets.all(30),
margin: EdgeInsets.all(20),
height: 230,
),
],
),
);
}
Container
有點型別我們 iOS
中的 UIView
控制元件,Container
沒設定寬高的情況下,Container
的大小由內部子控制元件撐起。padding
是內邊距,margin
是外邊距。
alignment
const Alignment(this.x, this.y)
: assert(x != null),
assert(y != null);
Container
有一個重要的屬性 alignment
,x
與 y
分別代表子控制元件在當前 Container
中的位置,x
為 -1
、0
、1
、分別代表子控制元件居左、居中、居右。y
為 -1
、0
、1
、分別代表子控制元件居上、居中、居下。
Flutter 佈局方式
Flutter
的佈局方式中有三個比較重要的子部件,Row
、Column
、Stack
分別代表橫向、縱向、多層,分別相當於座標軸的 x
、y
、z
軸。
Column
class LayoutColumnDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
alignment: Alignment(0.0, 0.0),
child: Column(
children: [
Container(color: Colors.red, child: Icon(Icons.add, size: 90,)),
Container(color: Colors.yellow, child: Icon(Icons.timelapse, size: 60,)),
Container(color: Colors.blue, child: Icon(Icons.error, size: 30,)),
],
),
);
}
}
Row
class LayoutRowDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
alignment: Alignment(1.0, 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(color: Colors.red, child: Icon(Icons.add, size: 90,)),
Container(color: Colors.yellow, child: Icon(Icons.timelapse, size: 60,)),
Container(color: Colors.blue, child: Icon(Icons.error, size: 30,)),
],
),
);
}
}
mainAxisAlignment
代表主軸的開始方向,Row
預設從左往右佈局,當把 mainAxisAlignment
設定為 MainAxisAlignment.end
的時候就是從右向左佈局,代表從結束位置開始。當佈局方式為 Row
的時候,Alignment
的 x
屬性對水平方向不起作用。
mainAxisAlignment: MainAxisAlignment.spaceBetween
spaceBetween
:代表子控制元件在主軸方向排列,剩下的空間平均分佈到子控制元件之間。
mainAxisAlignment: MainAxisAlignment.spaceAround
spaceAround
:剩下的空間平均分佈到子控制元件周圍。
mainAxisAlignment: MainAxisAlignment.spaceEvenly
spaceEvenly
:剩下的空間在子部件中間及子部件到螢幕邊緣平均分配。
crossAxisAlignment 交叉軸佈局
交叉軸就是主軸的垂直方向,Row
部件的交叉軸就是縱向。相對的其他方向的佈局也是類似。
crossAxisAlignment: CrossAxisAlignment.start
CrossAxisAlignment.start
: 點子控制元件在交叉軸方向都從內容頂部開始向下佈局。
class LayoutRowDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
alignment: Alignment(1.0, 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Container(color: Colors.red, child: Text('Hello', style: TextStyle(fontSize: 15))),
Container(color: Colors.yellow, child: Text('Flutter', style: TextStyle(fontSize: 30))),
Container(color: Colors.blue, child: Text('Demo', style: TextStyle(fontSize: 60))),
],
),
);
}
}
當 crossAxisAlignment
為 CrossAxisAlignment.baseline
的時候必須跟 textBaseline
屬性一起使用,用來設定文字的基準線的對齊方式。
Expanded
class LayoutExpandedDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
alignment: Alignment(1.0, 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Expanded(child: Container(color: Colors.red, child: Text('Hello', style: TextStyle(fontSize: 15)))),
Expanded(child: Container(color: Colors.yellow, child: Text('Flutter', style: TextStyle(fontSize: 30)))),
Expanded(child: Container(color: Colors.blue, child: Text('Demo', style: TextStyle(fontSize: 60)))),
],
),
);
}
}
通過上圖可以看到,被 Expanded
包裝的子控制元件會在主軸方向按螢幕的大小等分。當主軸方向為橫向的時候設定子控制元件的寬度就不會起作用。相同,當主軸方向為縱向的時候設定子控制元件的高度就不會起作用。
Stack
class LayoutStackDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
alignment: const Alignment(0, 0),
child: Stack(
children: [
Container(color: Colors.red, width: 200, height: 200, child: Icon(Icons.add)),
Container(color: Colors.yellow, width: 100, height: 100, child: Icon(Icons.timelapse)),
Container(color: Colors.blue, width: 50, height: 50, child: Icon(Icons.error)),
],
),
);
}
}
通過 Stack
佈局,Container
中的子控制元件會由內向外按順序疊加展示。
Positioned
children: [
Positioned(child: Container(color: Colors.red, width: 200, height: 200, child: Icon(Icons.add))),
Positioned(child: Container(color: Colors.yellow, width: 100, height: 100, child: Icon(Icons.timelapse)),left: 5,),
Positioned(child: Container(color: Colors.blue, width: 50, height: 50, child: Icon(Icons.error)),right: 10,),
],
當使用 Positioned
的時候,可以設定 left
或者 right
等屬性, left
或者 right
的值為 double
型別,可以設定子部件距離父控制元件的左邊或者右邊的間距。
AspectRatio
class LayoutAspectRatioDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
alignment: const Alignment(0, 0),
child: Container(
color: Colors.blue,
height: 200,
child: const AspectRatio(aspectRatio: 1 / 2, child: Icon(Icons.add))
),
);
}
}
Container
可以設定一個 AspectRatio
的子部件來影響當前 Container
控制元件的寬高比,當我們把高度設定為 200
的時候,控制元件的寬度會被自動設定為 100
。
- Swift - LeetCode - 學生出勤記錄 I
- Swift - LeetCode - 字串中的第一個唯一字元
- Swift - LeetCode - 猜數字大小
- Swift - LeetCode - 翻轉二叉樹
- Swift - LeetCode - 二叉樹的後序遍歷
- Swift - LeetCode - 二叉樹的前序遍歷
- Swift String、Moya 原始碼解析及高階函式
- Flutter 中 key 的原理及作用
- Flutter 生命週期及渲染原理
- Flutter 仿寫微信搜尋頁
- Flutter 網路請求類封裝及搜尋框實現
- Flutter 佈局聊天列表頁及網路資料處理
- Flutter 通訊錄索引條完善及聊天資料配置
- Flutter 仿寫微信通訊錄頁面
- Flutter 仿寫微信發現、我的頁面
- Flutter 專案搭建及工程配置
- 常用 Widget 部件介紹及 Flutter 佈局方式
- Flutter 之 Widget 部件體驗
- Dart 基礎語法
- 記憶體管理-弱引用分析