前言
- Flutter 作為Google出品的一個新興的跨平臺移動客戶端UI開發框架,正在被越來越多的開發者和組織使用,包括阿里的咸魚、騰訊的微信等。
示意圖
示意圖
今天,我主要講解Flutter
中布局方面的基礎布局組件,主要包括:
- Container
- Row
- Column
- Expanded
- Center
1. Container
1.1 定義
布局容器,屬于組合widget,內部有繪制widget、定位widget、尺寸widget
1.2 布局原理
由于Container結合了許多其他Widget;而每個Widget都有自己的布局行為,因此Container的布局行為十分復雜,具體介紹如下:
1.3 屬性說明
Container({
Key key, // 控制框架在widget重建時與哪些其他widget匹配
this.alignment, // 子Widget對齊,生效范圍:父Widget尺寸 > child Widget尺寸
this.padding, // 內邊距,即本Widget邊框和內容區之間距離
this.margin, // 外邊距:本Widget與父邊框的距離。
Color color, // Container背景色
Decoration decoration, // 繪制背景圖案,注:container背景色和decoration不能同時設置
this.foregroundDecoration, // 前景。設置了foregroundDecoration可能會遮蓋child內容,一般半透明遮蓋(蒙層)效果使用!
double width, // container的寬度,設置為double.infinity可以強制在寬度上撐滿,不設置,則根據child和父節點兩者一起布局。
double height, // container的高度,設置為double.infinity可以強制在高度上撐滿。
BoxConstraints constraints, // 添加到child上額外的約束條件,用于設置child的寬高范圍值
this.child, // 控件內容widget。
})
關于Decoratiton的使用,具體請看文章:
1.4 具體使用
import 'package:flutter/material.dart';// Material UI組件庫
void main() => runApp(MyApp());
// 無狀態控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象,用來定義當前應用打開的時候,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Container(
alignment: Alignment.center,// 對齊
padding: const EdgeInsets.all(5.0),// 內邊距
margin: const EdgeInsets.all(10.0),// 外邊距
color: Colors.grey,// 背景色
// 裝飾(無法和color一起設置)
// decoration: new BoxDecoration(
// border: new Border.all(width: 2.0, color: Colors.red),
// borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
// image: new DecorationImage(
// image: new AssetImage('assetImage/photo.jpg'),
// centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
// ),
// ),
// 添加到child上額外的約束條件,用于設置child的寬高范圍值
constraints: new BoxConstraints.expand(
height: Theme
.of(context)
.textTheme
.display1
.fontSize * 1.1 + 200.0,
),
// 設置子空間
child: Text("carson ho Demo",),
)
);
}
}
1.5 測試效果
2. Row
2.1 作用
水平展示多個子控件的控件,即將一系列控件排成一行顯示
注:該控件無法滾動。若超過一行則會報錯,應考慮使用ListView類。
2.2 概念解析:主軸 & 縱軸
對于線性布局:
- 若布局沿水平方向(如Row),那么主軸 = 水平方向、縱軸 = 垂直方向
- 若布局沿垂直方向(如Colum),那么主軸 = 垂直方向、縱軸 = 水平方向
2.3 屬性說明
// 屬性說明
Row({
Key key, // 全局key來唯一標識子widget
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 子控件放置方式
MainAxisSize mainAxisSize = MainAxisSize.max, // 子控件應該如何沿著主軸放置
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 子控件對齊方式
TextDirection textDirection, // 排列方式:從左到右,還是從右到左排序
VerticalDirection verticalDirection = VerticalDirection.down, // 垂直排序
TextBaseline textBaseline, // 對齊文本的水平線
List<Widget> children = const <Widget>[], // 子控件
})
// 屬性詳解
// 1. mainAxisAlignment
// 說明:子控件根據主軸的對齊方式,枚舉對象(默認值為start)
enum MainAxisAlignment {
start, // 內部的子組件將從主軸起始位置開始排列(正向排列)
end, // 內部的子組件將從主軸末尾位置開始排列(反向排列)
center, // 內部的子組件將從主軸中間位置開始排列(居中)
spaceBetween, // 內部的首尾子組件靠近首尾兩端,其余子組件居中排列且組件間的間距一樣
spaceAround, // 內部的子組件居中排列,且每個子組件的左右邊距一樣大
spaceEvenly, // 內部的子組件居中顯示,每個空間的左邊和右邊都有相同的間距
}
// 2. mainAxisSize
// 說明:子控件如何放置,枚舉對象(默認值為max)
enum MainAxisSize {
min, // 控件盡可能小,相當于wrap_content(取此值時,上面的MainAxisAlignment 無效),
max, // 控件盡可能大,相當于match_parent
}
// 3. crossAxisAlignment
// 說明:子控件對于縱軸的對齊方式,當子控件高度不一樣時,如何被放置在主軸(中心軸),而MainAxisAlignment 決定了子控件間的間隔
enum CrossAxisAlignment {
start, // 內部的子組件將從非主軸起始位置開始排列(正向排列)
end, // 內部的子組件將從非主軸末尾位置開始排列(反向排列)
center, // 內部的子組件將從非主軸中間位置開始排列(居中)
stretch, // 內部的子組件將從非主軸中間位置開始排列,并且完全填充非主軸方向
baseline, // 內部的子組件將從baseline的方向對齊,這個需要設置textBaseline屬性,不然的話會報錯
}
// 4. textBaseline
// 說明:對齊文本的水平線
enum TextBaseline {
alphabetic, // 用于對齊字母字符的字形底部的水平線
ideographic, // 用于對齊表意文字的水平線
}
// 5. textDirection
// 說明:子控件排序方向 (一般不用設置,除非想反轉子控件排序)
// Row 使用 TextDirection
// Column 使用 VerticalDirection
enum VerticalDirection {
up, // 子控件從下到上排序
down, // 子控件從上到下排序
}
enum TextDirection {
rtl, // 子控件從右到左排序
ltr, // 子控件從左到右排序
}
// 6. children
// 設置子控件
2.4 具體使用
import 'package:flutter/material.dart'; // Material UI組件庫
void main() => runApp(MyApp());
// 無狀態控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象,用來定義當前應用打開的時候,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Text(" Carson Ho "),
Text(" Kobe Bryant "),
Text(" LeBorn James "),
Text(" Michael Jordan "),
],
),
);
}
}
2.5 效果圖
3. Column
3.1 作用
垂直方向展示多個子控件的控件,即將一系列控件排成一列顯示
3.2 屬性說明
屬性類似于Row的屬性,主要包括:
// 屬性說明
Column({
Key key, // 全局key來唯一標識子widget
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 子控件放置方式
MainAxisSize mainAxisSize = MainAxisSize.max, // 子控件應該如何沿著主軸放置
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 子控件對齊方式
TextDirection textDirection, // 排列方式:從左到右,還是從右到左排序
VerticalDirection verticalDirection = VerticalDirection.down, // 垂直排序
TextBaseline textBaseline, // 對齊文本的水平線
List<Widget> children = const <Widget>[], // 子控件
})
// 屬性詳解
// 1. mainAxisAlignment
// 說明:子控件根據主軸的對齊方式,枚舉對象(默認值為start)
enum MainAxisAlignment {
start, // 內部的子組件將從主軸起始位置開始排列(正向排列)
end, // 內部的子組件將從主軸末尾位置開始排列(反向排列)
center, // 內部的子組件將從主軸中間位置開始排列(居中)
spaceBetween, // 內部的首尾子組件靠近首尾兩端,其余子組件居中排列且組件間的間距一樣
spaceAround, // 內部的子組件居中排列,且每個子組件的左右邊距一樣大
spaceEvenly, // 內部的子組件居中顯示,每個空間的左邊和右邊都有相同的間距
}
// 2. mainAxisSize
// 說明:子控件如何放置,枚舉對象(默認值為max)
enum MainAxisSize {
min, // 控件盡可能小,相當于wrap_content(取此值時,上面的MainAxisAlignment 無效),
max, // 控件盡可能大,相當于match_parent
}
// 3. crossAxisAlignment
// 說明:子控件對于縱軸的對齊方式,當子控件高度不一樣時,如何被放置在主軸(中心軸),而MainAxisAlignment 決定了子控件間的間隔
enum CrossAxisAlignment {
start, // 內部的子組件將從非主軸起始位置開始排列(正向排列)
end, // 內部的子組件將從非主軸末尾位置開始排列(反向排列)
center, // 內部的子組件將從非主軸中間位置開始排列(居中)
stretch, // 內部的子組件將從非主軸中間位置開始排列,并且完全填充非主軸方向
baseline, // 內部的子組件將從baseline的方向對齊,這個需要設置textBaseline屬性,不然的話會報錯
}
// 4. textBaseline
// 說明:對齊文本的水平線
enum TextBaseline {
alphabetic, // 用于對齊字母字符的字形底部的水平線
ideographic, // 用于對齊表意文字的水平線
}
// 5. textDirection
// 說明:子控件排序方向 (一般不用設置,除非想反轉子控件排序)
// Row 使用 TextDirection
// Column 使用 VerticalDirection
enum VerticalDirection {
up, // 子控件從下到上排序
down, // 子控件從上到下排序
}
enum TextDirection {
rtl, // 子控件從右到左排序
ltr, // 子控件從左到右排序
}
// 6. children
// 設置子控件
3.3 具體使用
import 'package:flutter/material.dart'; // Material UI組件庫
void main() => runApp(MyApp());
// 無狀態控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象,用來定義當前應用打開的時候,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.down,
children: <Widget>[
Text(" Carson Ho "),
Text(" Kobe Bryant "),
Text(" LeBorn James "),
Text(" Michael Jordan "),
],
),
);
}
}
3.4 具體效果
4. Expanded
4.1 作用
按比例伸縮 / 擴展 Row、Column和Flex子組件所占用的空間大小
4.2 屬性說明
const Expanded({
Key key, // 唯一標識符
int flex = 1, // 彈性系數,默認值 = 1
// 若為 0 或 null,則 child 是沒有彈性的,即不會被擴伸占用的空間。
// 若大于 0,所有的Expanded按照其flex的比例來分割主軸的全部空閑空間。
@required Widget child, // 子控件
})
4.3 具體使用
import 'package:flutter/material.dart'; // Material UI組件庫
void main() => runApp(MyApp());
// 無狀態控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象,用來定義當前應用打開的時候,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體:配合Row使用(采用兩個容器Container來展示)
body: new Row(
children: <Widget>[
Expanded(
flex: 2, // 占2份空間
child: Container(
color: Colors.red,
)),
Expanded(
flex: 1, // 占1份空間
child: Container(
color: Colors.green,
)),
],
),
);
}
}
4.4 測試效果
5. Center
中心定位控件,能夠將子控件放在其內部中心
class Page extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text("正中央"), // 將text放到文本中央
);
}
}
總結
本文全面介紹了Flutter
常用的基礎布局組件,總結如下:
接下來推出的文章,我將繼續講解Flutter的相關知識,包括使用語法、實戰等,感興趣的讀者可以繼續關注我的博客哦:Carson_Ho的Android博客
請點贊!因為你們的贊同/鼓勵是我寫作的最大動力!
相關文章閱讀
Android開發:最全面、最易懂的Android屏幕適配解決方案
Android開發:史上最全的Android消息推送解決方案
Android開發:最全面、最易懂的Webview詳解
Android開發:JSON簡介及最全面解析方法!
Android四大組件:Service服務史上最全面解析
Android四大組件:BroadcastReceiver史上最全面解析
歡迎關注Carson_Ho的簡書!
不定期分享關于安卓開發的干貨,追求短、平、快,但卻不缺深度。