1、flutter的開始
1、認識檔案夾

| 檔案夾名稱 | 作用 |
|---|---|
| android | android平臺相關代碼 |
| ios | ios平臺相關代碼 |
| lib | flutter相關代碼,主要撰寫的代碼放入該檔案夾 |
| test | 用于存放測驗代碼 |
| pubspec.yaml | 組態檔,專案相關資訊,一般存放第三方庫的依賴 |
2、入口檔案/入口方法
入口檔案:flutter專案的lib目錄里面都有一個main.dart這個檔案就是flutter的入口檔案
入口方法:main.dart檔案中的
void main() {
runApp(MyApp());
}
//也可也簡寫一下
void main()=>runApp(MyApp());
其中main方法是dart的入口方法,runApp方法是flutter的入口方法,MyApp是自定義的一個組件,
2、flutter基本
從最根本的開始哦,
1、Helloworld
import 'package:flutter/material.dart';
void main() {
runApp( Center(
child: Text(
'CDX',
textDirection: TextDirection.ltr,
)
));
}
實作效果:

2、自定義組件
在flutter中自定義組件其實就是一個類,這個類需要繼承StatelessWidget/StatefulWidget,
StatelessWidget:是無狀態組件,狀態不可變的widget,
StatefulWidget:是有狀態組件,持有的狀態可能在widget生命周期改變,
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'CDX111',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Colors.yellow,
),
));
}
}
實作效果:

3、組件:MaterialApp/Scaffold
1、MaterialApp組件是一個方便的Widget,它封裝了應用程式實作Material Design所需要的一些Widget,一般作為頂層widget使用,
2、Scaffold組件是Material Design布局結構的基本實作,此類提供了用于顯示drawer、snackbar和底部sheet的API,
代碼塊:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'CDX111',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Colors.yellow,
),
));
}
}
完整代碼:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'CDX111',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Colors.yellow,
),
));
}
}
實作效果:

4、組件:Container/Text 詳解
1、Container組件
該組件可以被用來看作是我們之前的一個div,其實他就是一個物件,我們來看一下他的建構式吧,

Container組件屬性描述
| 屬性名 | 型別 | 說明 |
|---|---|---|
| key | Key | Container 一識別符號,用于查找更新 |
| alignment | AlignmentGeometry | 控制child 的對齊方式,如果Container或者 Container 父節點尺寸大于child 的尺寸,這個屬性設定會起作用,有很多種對齊方式 |
| padding | EdgelnsetsGeometry | Decoration內部的空白區域,如果有child的話,child 位于padding 內部 |
| color | Color | 用來設定 Contain 背景色,如果foregroundDecoration設定的話,可能會遮蓋color效果 |
| decoration | Decoration | 繪制在child后面的裝飾,設定了 Decoration 話,就不能設定color 屬性,否則會報錯,此時應該在 Decoration中進行顏色的設定 |
| foregroundDecoration | Decoration | 繪制在child前面的裝飾 |
| width | double | Container的寬度,設定為double.infinity可以強制在寬度上撐滿,不設定,則根據child和父節點兩者一起布局 |
| height | double | Container的高度,設定為double.infinity可以強制在高度上撐滿 |
| constraints | BoxConstraints | 添加到child上額外的約束條件 |
| margin | EdgelnsetsGeometry | 圍繞在Decoration和child之外的空白區域,不屬于內容區域 |
| transform | Matrix4 | 設定Container的變換矩陣,型別為Matrix4 |
| child | Widget | Container中的內容Widget |
2、Text組件
Text組件屬性描述
| 屬性名 | 型別 | 默認值 | 說明 |
|---|---|---|---|
| data | String | 資料為要顯示的文本 | |
| maxLines | int | 0 | 文本顯示的最大行數 |
| style | TextStyle | null | 文本樣式,可定義文本的字體大小、顏色、粗細等 |
| textAlign | TextAlign | TextAlign.center | 文本水平方向對齊方式,取值有center、end、justify、left、right、start、values |
| textDirection | TextDirection | TextDirection.ltr | 文本書寫方向,ltr從左到右,rtl從右到左 |
| textScaleFactor | double | 1.0 | 字體縮放系數 |
| textSpan | TextSpan | null | 文本塊 |
3、示例
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Text(
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
style: TextStyle(
fontSize: 16.0,
color: Colors.red,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.italic,
decoration: TextDecoration.lineThrough,
decorationColor: Colors.white,
decorationStyle: TextDecorationStyle.dashed),
),
height: 300.0,
width: 300.0,
decoration: BoxDecoration(
color: Colors.green,
border: Border.all(color: Colors.blue, width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(150))
),
transform: Matrix4.rotationZ(0.3),
),
);
}
}
效果:

5、圖片組件
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在HomeContent中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介紹
1、new Image:從ImageProvideer 獲取圖片
2、new Image.asset:加載資源圖片
3、new Image.file:加載本地圖片檔案
4、new Image.netWork:加載網路圖片
5、new Image.memory:加載Uint8List資源圖片,
Image組件屬性描述
| 屬性名 | 型別 | 說明 |
|---|---|---|
| image | ImageProvider | 抽象類,需要自己實作獲取圖片資料的操作 |
| width/hei ght | double | Image顯示區域的寬度和高度設定 |
| fit | Boxfit | 圖片填充模式 |
| color | Color | 圖片顏色 |
| colorBlendMode | BlendMode | 在對圖片進行手動處理的時候,可能會用到圖片混合如改變圖片的顏色,此屬性可以對顏色進行混合處理, |
| alignment | Alignment | 控制圖片的擺放位置 |
| repeat | ImageRepeat | 設定圖片重復模式 |
| centerSlice | Rect | 當圖片需要被拉伸時使用 |
| matchTextDirection | booI | 該屬性與Directionlity配合使用 |
| gaplessPlayback | bool | 當ImageProvide發生變化后,重新加載圖片的程序中,原圖片的展示是否保留 |
BoxFit取值描述
| 取值 | 描述 |
|---|---|
| Boxfit.fill | 全圖顯示,顯示可能拉伸,充滿 |
| Boxfit.contain | 全圖顯示,顯示原比例,不需充滿 |
| Boxfit. cover | 顯示可能拉伸,可能裁剪,充滿 |
| BoxFit.fitWidth | 顯示可能拉伸,可能裁剪,寬度充滿 |
| BoxFit.fitHeight | 顯示可能拉伸,可能裁剪,高度充滿 |
| Boxfit.none | 原始大小 |
| BoxFit.scaleDown | 效果和BoxFit.contain差不多,但是此屬性不允許顯示超過源圖片大小,即可小不可大 |
2、遠程圖片示例
mage.network(src)
簡單示例:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Image.network(
"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
colorBlendMode: BlendMode.screen,
fit: BoxFit.cover,),
width: 300,
height: 300,
decoration: BoxDecoration(
color: Colors.green,
),
),
);
}
}
效果:

3、實作圓角以及圓形圖片
1、使用borderRadius和BoxFit.cover實作
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 300,
height: 300,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(150),//*********
image: DecorationImage(
image: NetworkImage( "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
),
fit: BoxFit.cover,//************
),
),
));
}
}
效果:

2、使用ClipOval實作
1、首先看clipOval處理的效果
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: ClipOval(
child: Image.network("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",),
),
));
}
}
效果:

2、繼續變圓
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: ClipOval(
child: Image.network("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
height: 300,
width: 300,
fit: BoxFit.cover,),
),
));
}
}
效果:

2、本地圖片
1、相關檔案夾的創建與組態檔修改

2、示例
1、代碼
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Image.asset("images/1.jpg"),
));
}
}
2、效果

6、串列組件
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在HomeContent中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介紹
串列大致有以下分類
1、水平的串列
2、垂直的串列
3、資料量非常大的串列
4、矩陣式的串列
ListView組件的基本屬性
| 屬性名 | 型別 | 默認值 | 說明 |
|---|---|---|---|
| scrollDirection | Axis | Axis.vertical | 串列的排列方向,Axis.vertical為垂直方法式默認值,Axis.horizontal為水平方法 |
| padding | EdgelnsetsGeometry | 串列內部的空白區域,如果有child的話,child位于padding內部 | |
| reverse | bool | false | 組件排列反向 |
| children | List | 串列元素,注意List元素全部為Widget |
2、垂直串列
代碼:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
leading: Image.asset("images/1.jpg"),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
trailing: Icon(Icons.search),
),
ListTile(
leading: Icon(Icons.padding),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
leading: Icon(Icons.games),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
leading: Icon(Icons.ac_unit_sharp),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
leading: Icon(Icons.tab),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
],
);
}
}
效果:

3、水平串列
代碼:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 200,
child:ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.green,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.grey,
),
Container(
width: 100,
height: 100,
color: Colors.deepOrange,
),
],
)
);
}
}
效果:

4、動態串列
代碼:
class HomeContent extends StatelessWidget {
List<Widget> getData() {
List<Widget> list = new List();
for (var i = 1; i <= 7; i++) {
list.add(ListTile(
title: Text("xxxxxx$i個"),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return Container(child: ListView(children: this.getData()));
}
}
ListView.builder
class HomeContent extends StatelessWidget {
List list = new List();
HomeContent() {
for (var i = 1; i <= 7; i++) {
list.add("xxxxxx$i個");
}
}
@override
Widget build(BuildContext context) {
return Container(child: ListView.builder(
itemCount: this.list.length,
itemBuilder: (context,index){
return ListTile(
title: Text(this.list[index]),
);
},
));
}
}
效果:

7、GridView組件
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
GridView組件屬性及描述
| 屬性名 | 型別 | 默認值 | 說明 |
|---|---|---|---|
| scrollDirection | Axis | Axis.vertical | 滾動的方向,有垂直和水平兩種,默認為垂直方向 |
| reverse | bool | false | 默認是從上或者左向下或者向右滾動的,這個屬性控制是否反向,默認值為false,即不反向滾動 |
| controller | ScrollController | 控制child滾動時候的位置 | |
| primary | bool | 是否是與父節點的PrimaryScrollcontroller所關聯的主滾動視圖 | |
| physics | ScrollPhysics | 滾動的視圖如何回應用戶的輸入 | |
| shrinkWrap | bool | false | 滾動方向的滾動視圖內容是否應該由正在查看的內容所決定 |
| padding | EdgeinsetsGeometry | 四周的空白區域 | |
| gridDelegate | SliverGridDelegate | 控制GridView中子節點布局的delegate | |
| cacheExtent | double | 快取區域 |
1、通過GridView.count實作網格布局
代碼:
class Demo extends StatelessWidget {
List<Widget> getData() {
List<Widget> list = new List();
for (var i = 0; i < 20; i++) {
list.add(Container(
alignment: Alignment.center,
child: Text(
'xxxxx $i xxxx',
style: TextStyle(color: Colors.white,fontSize: 20),
),
color: Colors.blue,
));
}
return list;
}
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisSpacing: 10.0, //水平子Widget之間的距離
mainAxisSpacing: 10.0, //垂直widget之間距離
padding: EdgeInsets.all(10),
crossAxisCount: 3, //控制一行有多少個Widget
childAspectRatio: 0.7,//寬度和高度的比例
children: this.getData(),
);
}
}
效果:

2、通過GridView.builder實作網格布局
代碼:
class Demo extends StatelessWidget {
Widget getData(context, index) {
return Container(
child: Column(
children: <Widget>[
Image.asset("images/1.jpg"),
SizedBox(height: 12),
Text(
"xxxxxxxx",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20),
)
],
),
decoration: BoxDecoration(
border: Border.all(color: Colors.blue, width: 1),
),
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
// padding: EdgeInsets.all(10),
// crossAxisCount: 3, //控制一行有多少個Widget
// childAspectRatio: 0.7,//寬度和高度的比例
// children: this.getData(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10.0, //水平子Widget之間的距離
mainAxisSpacing: 10.0, //垂直widget之間距離
crossAxisCount: 3, //控制一行有多少個Widget
),
itemCount: 10,
itemBuilder: this.getData,
);
}
}
效果:

8、頁面布局 Padding/Row/Column/Expanded
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
GridView組件屬性及描述
1、Padding組件
在html中常見的布局標簽都有padding屬性,但是Fliuuter中很多widget是沒有padding屬性的,這時候我們可以用Padding組件處理容器與子元素之間的間距
| 屬性 | 說明 |
|---|---|
| padding | padding值,EdgeInsetss設定填充的值 |
| child | 子組件 |
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.count(
padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
crossAxisCount: 3, //控制一行有多少個Widget
childAspectRatio: 1.7,//寬度和高度的比例
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
],
);
}
}
效果:

2、Row水平布局組件
屬性介紹:
| 屬性 | 說明 |
|---|---|
| mainAxisAlignment | 主軸的排序方式 |
| crossAxisAlignment | 次軸的排序方式 |
| children | 組件子元素 |
3、Column垂直布局組件
實作一個圖示組件:實作傳入圖示(顏色和大小動態)
代碼:
class IconDemo extends StatelessWidget {
double size = 32.0;
Color color = Colors.red;
IconData icon;
IconDemo(this.icon, {this.color, this.size});
@override
Widget build(BuildContext context) {
return Container(
height: 100.0,
width: 100.0,
color: this.color,
child: Center(
child: Icon(
Icons.home,
size: 32,
color: Colors.white,
),
),
);
}
}
通過上述組件測驗Row的排序
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 600.0,
width: 600.0,
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
IconDemo(
Icons.home,
color: Colors.green,
),
IconDemo(
Icons.search,
color: Colors.red,
),
IconDemo(
Icons.fit_screen,
color: Colors.green,
),
],
)
);
}
}
class IconDemo extends StatelessWidget {
double size = 32.0;
Color color = Colors.red;
IconData icon;
IconDemo(this.icon, {this.color, this.size});
@override
Widget build(BuildContext context) {
return Container(
height: 100.0,
width: 100.0,
color: this.color,
child: Center(
child: Icon(
Icons.home,
size: 32,
color: Colors.white,
),
),
);
}
}
效果:

4、Expanded組件
Flutter中Expanded組件類似Web中的Flex布局
Expanded可以用在Row和Column布局中
| 屬性 | 說明 |
|---|---|
| flex | 元素占整個父Row/Column的比例 |
| child | 子元素 |
代碼:(未包含上述IconDemo組件的代碼)
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child: IconDemo(
Icons.home,
color: Colors.green,
),
),
Expanded(
flex: 2,
child: IconDemo(
Icons.search,
color: Colors.red,
),
),
],
);
}
}
效果:

5、相關案例
實作一個類似于下圖的布局

代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
height: 200,
color: Colors.blue,
child: Text("xxxxxxxxxx"),
),
)
],
),
SizedBox(height: 10),
Row(children: <Widget>[
Expanded(
flex: 2,
child: Container(
height: 180,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
))),
Expanded(
flex: 1,
child: Container(
height: 180,
child: ListView(children: <Widget>[
Container(
height: 85,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
)),
SizedBox(height: 10),
Container(
height: 85,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
))
]))),
]),
],
);
}
}
效果:

9、頁面布局 Stack層疊組件/Stack與Aligin/Stack與Positioned
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、Stack組件
| 屬性 | 說明 |
|---|---|
| alignment | 配置所有子元素的顯示位置 |
| children | 子組件 |
stack效果:有點像元素重疊一樣,下面展示文字和容器效果
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
height: 400,
width: 300,
color: Colors.red,
),
Text("xxxxxxxxxxx")
],
);
}
}
效果:

通過alignment屬性進行位置移動

還可以是坐標
alignment: Alignment(0,0),
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
// alignment: Alignment.center,
// alignment: Alignment(0,0),
alignment: Alignment.center,
children: <Widget>[
Container(
height: 400,
width: 300,
color: Colors.red,
),
Text("xxxxxxxxxxx")
],
);
}
}
效果:

2、align/positiond
上述stack如果里面有兩個文本的話,就會導致兩個文本出現重疊的現象如下:
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
// alignment: Alignment.center,
// alignment: Alignment(0,0),
alignment: Alignment.center,
children: <Widget>[
Container(
height: 400,
width: 300,
color: Colors.red,
),
Text("xxxxxxxxxxx"),
Text("ddddddddddd"),
],
);
}
}
效果:

使用align
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 400,
width: 400,
color: Colors.blue,
child: Stack(children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: Icon(Icons.help, size: 40, color: Colors.white),
),
Align(
alignment: Alignment.center,
child: Icon(Icons.search, size: 40, color: Colors.white),
),
Align(
alignment: Alignment.bottomRight,
child: Icon(Icons.home_filled, size: 40, color: Colors.white),
),
]),
),
);
}
}
效果:

使用positiond
| 屬性 | 說明 |
|---|---|
| top | 子元素距離頂部的距離 |
| bottom | 子元素距離底部的距離 |
| left | 子元素距離左側的距離 |
| right | 子元素距離右側的距離 |
| child | 子組件 |
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 400,
width: 400,
color: Colors.blue,
child: Stack(children: <Widget>[
Positioned(
left: 10,
child: Icon(Icons.help, size: 40, color: Colors.white),
),
Positioned(
bottom: 0,
child: Icon(Icons.search, size: 40, color: Colors.white),
),
Positioned(
right: 0,
child: Icon(Icons.home_filled, size: 40, color: Colors.white),
),
]),
),
);
}
}
效果:

10、AspectRatio組件/Card組件
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、AspectRatio
AspectRatio的作用是根據設定調整子元素child的寬高比,
AspectRatio首先會在布局限制條件允許的范圍內盡可能的擴展,widget的寬度是由寬度和比率決定的,類似于BoxFit中的contain,按照固定比率去盡量占滿區域,
如果在滿足所有限制條件過后無法找到一個可行的尺寸,AspectRatio最終將會去優先適應布局限制條件,而忽略所設定的比率
| 屬性 | 說明 |
|---|---|
| aspectRatio | 寬高比,最終可能不會根據這個值去布局,具體要看綜合因素,外層是否允許按照這種比例進行布局,這只是一個參考值 |
| child | 子組件 |
代碼:(長是高的2倍例子)
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 200,
child: AspectRatio(
aspectRatio: 2.0/1.0,//外層的200,會是里面的container長200高100
child: Container(
color: Colors.red,
),
),
);
}
}
2、Card
Card是卡片組件塊,內容可以由大多數型別的Widget構成,Card具有圓角和陰影,這讓它看起來有立體感,
| 屬性 | 說明 |
|---|---|
| margin | 外邊距 |
| child | 子組件 |
| Shape | Card的陰影效果,默認的陰影效果為圓角的長方形邊, |
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Card(
margin:EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title:Text('chidaoxian'),
subtitle: Text('前端開發工程師'),
),
ListTile(
title:Text('電話:12323432141234123'),
),
ListTile(
title:Text('地址:xxxxxx'),
),
],
),
),
Card(
margin:EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title:Text('chidaoxian'),
subtitle: Text('前端開發工程師'),
),
ListTile(
title:Text('電話:12323432141234123'),
),
ListTile(
title:Text('地址:xxxxxx'),
),
],
),
),
],
);
}
}
效果:

11、Wrap組件
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介紹
wrap組件可以實作流布局,單行的Wrap跟Column表現幾乎一致,單列的Wrap則跟Row表現幾乎一致,但Row與Column都是單行單列,Wrap則突破了這個限制,mainAxis上空間不足時,則向crossAxis上去擴展顯示,
| 屬性 | 說明 |
|---|---|
| direction | 主軸的方法,默認水平 |
| alignment | 主軸的對齊方式 |
| spacing | 主軸方向上的間距 |
| textDirection | 文本方向 |
| verticalDirection | 定義了children擺放順序,默認是down,見flex相關屬性介紹 |
| runAlignment | run的對齊方式,run可以理解為新的行或者列,如果是水平方向布局的話,run可以理解為新的一行 |
| runSpacing | run的間距 |
2、wrap實體
代碼:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Wrap(
spacing:10,
// runSpacing:5,
children: <Widget>[
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
]);
}
}
class MyButton extends StatelessWidget {
final String text;
const MyButton(this.text, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text(this.text),
textColor: Theme.of(context).accentColor,
onPressed: () {},
);
}
}
效果:

12、StatefulWidget有狀態組件、頁面上系結資料、改變頁面資料
基礎代碼塊:(本節代碼基礎部分,其余效果展示代碼均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介紹
StatefulWidget是有狀態組件,持有的狀態可能在Widget生命周期改變,通俗的講:如果我們想改變頁面中的資料的話這個時候就需要用到StatefulWidget,
2、有狀態組件/資料系結
代碼:
class Demo extends StatefulWidget {
Demo({Key key}) : super(key: key);
@override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
int countNum = 0;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SizedBox(height: 20,),
Chip(label: Text('${this.countNum}')),
SizedBox(height: 20,),
RaisedButton(
child: Text('按鈕'),
onPressed: (){
setState(() {
this.countNum++;
});
},
)
],
);
}
}
效果:

13、ButtonNavigationBar組件
1、介紹
ButtonNavigationBar 是底部導航條,可以讓我們定義底部Tab切換,buttonNavigationBar是Scaffold組件引數,
| 屬性名 | 型別 | 說明 |
|---|---|---|
| currentlndex | int | 當前索引,用來切換按鈕控制 |
| fixedColor | Color | 選中按鈕的顏色,如果沒有指定值,則用系統主題色 |
| iconSize | double | 按鈕圖示大小 |
| items | List | 底部導航調按鈕集,每一項是一個BottomNavigationBarItem,有icon圖示及title文本屬性 |
| onTap | ValueChanged | 按下其中某一個按鈕回呼事件,需要根據回傳的索引設定當前索引 |
2、實體
1、效果:
底部導航切換頁面效果:


代碼介紹:


代碼:
1、main.dart的代碼
import 'package:flutter/material.dart';
import 'package:flutter_app01/pages/tabs/Home.dart';
import 'pages/tabs/Tabs.dart';
import 'pages/tabs/ddd.dart';
import 'pages/tabs/Setting.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Tabs(),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
class Tabs extends StatefulWidget {
Tabs({Key key}) : super(key: key);
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int currentIndex = 0;
List pageList = [
HomePage(),
SettingPage(),
DDDPage(),
];
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: this.pageList[this.currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: this.currentIndex,
onTap: (int index) {
setState(() {
this.currentIndex = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首頁',
),
BottomNavigationBarItem(
icon: Icon(Icons.my_library_books),
label: '我的',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings_applications),
label: '設定',
),
],
),
),
);
}
}
2、Tabs.dart的代碼
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
Tabs({Key key}) : super(key: key);
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Text('xxx'),
bottomNavigationBar: BottomNavigationBar(
currentIndex: this.currentIndex,
onTap: (int index) {
setState(() {
this.currentIndex = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首頁',
),
BottomNavigationBarItem(
icon: Icon(Icons.my_library_books),
label: '我的',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings_applications),
label: '設定',
),
],
),
),
);
}
}
3、Home.dart的代碼(Home.dart/Setting.dart代碼類似)
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('HomePage'),
);
}
}
14、Flutter中的基本路由
flutter中的路由通俗的講就是頁面跳轉,在flutter中通過Navigator組件管理路由導航,并提供了管理堆疊的方法,如:Navigator.push 和Navigator.pop
flutter中給我們提供了兩種配置路由跳轉的方式:1、基本路由 2、命名路由
1、簡單路由跳轉

代碼:
import 'package:flutter/material.dart';
import '../Search.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('跳轉搜索頁面'),
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (context)=> SearchPage()
)
);
},
),
],
);
}
}
2、跳轉傳值

代碼:
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
SearchPage({Key key}) : super(key: key);
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
String title ;
_SearchPageState({this.title = 'cdx'});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("${this.title}頁面"),
),
body: Text("內容區域"),
);
}
}
3、回傳

代碼:
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
SearchPage({Key key}) : super(key: key);
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
String title ;
_SearchPageState({this.title = 'cdx'});
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Text('回傳'),
onPressed: (){
Navigator.of(context).pop();
},
),
appBar: AppBar(
title: Text("${this.title}頁面"),
),
body: Text("內容區域"),
);
}
}
效果:

15、Flutter命名路由
1、不攜帶引數
main.dart檔案配置:**

路由跳轉方式:

2、攜帶引數
Routes.dart檔案
import 'package:flutter/material.dart';
import 'package:flutter_app01/pages/tabs/Tabs.dart';
import 'package:flutter_app01/pages/tabs/ddd.dart';
import 'package:flutter_app01/pages/tabs/Setting.dart';
import 'package:flutter_app01/pages/Search.dart';
import 'package:flutter_app01/pages/tabs/Home.dart';
final routes = {
'/': (context, {arguments}) => Tabs(),
'/home': (context, {arguments}) => HomePage(),
'/ddd': (context, {arguments}) => DDDPage(),
'/setting': (context, {arguments}) => SettingPage(),
'/search': (context, {arguments}) => SearchPage(arguments: arguments),
};
//主要方法
var onGenerateRoute = (RouteSettings settings) {
final String name = settings.name;
final Function pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context, argumens: settings.arguments));
return route;
} else {
final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
};
main.dart檔案
import 'package:flutter/material.dart';
import 'package:flutter_app01/routes/Routes.dart';
void main() {
runApp(MyApp());
}
//自定義組件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.green,
),
// home: Tabs(),
initialRoute: '/', //初始化的時候加載的路由
onGenerateRoute: onGenerateRoute,
);
}
}
16、路由替換/回傳根路由
1、替換路由
就是替換當前的頁面,

2、回傳跟路由

待入的組件表格屬性介紹
Form組件
| 屬性名 | 型別 | 說明 |
|---|---|---|
| key | Key | 組件在整個Widget樹中的key值 |
| autovalidate | bool | 是否自動提交表單 |
| child | Widget | 組件child只能有一個子組件 |
| onChanged | VoidCallback | 當FormFiled值改變時的回呼函式 |
TextFromField組件
| 屬性名 | 型別 | 說明 |
|---|---|---|
| autovalidate | bool | 自動驗證值 |
| initialValue | T | 表單欄位初始值 |
| onSaved | FormFieldSetter | 當Form表單呼叫保存方法Save時回呼函式 |
| validator | FormFieldValidator | Form表單驗證器 |
Material Design風格組件
| 組件名稱 | 中文名稱 | 簡單說明 |
|---|---|---|
| AppBar | 應用按鈕組件 | 應用的工具按鈕 |
| AlertDialog | 對話框組件 | 有操作按鈕的對話框 |
| BottomNavigationBar | 底部導航條組件 | 底部導航條,可以很容易地在tap之間切換和瀏覽頂級視圖 |
| Card | 卡片組件 | 帶有邊框陰影的卡片組件 |
| Drawer | 抽屜組件 | Drawer抽屜組件可以實作類似抽屜拉開關閉的效果 |
| FloatingActionButton | 浮動按鈕組件 | 應用的主要功能操作按鈕 |
| FlatButton | 扁平按鈕組件 | 扁平化風格的按鈕 |
| MaterialApp | Material應用組件 | Material App代表使用紙墨設計風格的應用 |
| PopupMenuButton | 彈出選單組件 | 彈出選單按鈕 |
| Scaffold | 腳手架組件 | 實作了基本的Material Design 布局 |
| SnackBar | 輕量提示組件 | 一個輕量級訊息提示組件,在螢屏的底部顯示 |
| SimpleDialog | 簡單對話框組件 | 簡單對話框組件,只起提示作用,沒有互動 |
| TabBar | 水平選項卡及視圖組件 | 一個顯示水平選項卡的Material Design組件 |
| TextField | 文本框組件 | 可接受應用輸入文本的組件 |
MaterialApp
| 屬性名 | 型別 | 說明 |
|---|---|---|
| title | String | 應用程式的標題,該標題出現在如下位置:Android:任務管理器的程式快照之上 IOS:程式切換管理器 |
| theme | ThemeData | 定義應用所使用的主題顏色,可以指定一個主題中每個控制元件的顏色 |
| color | Color | 應用的主要顏色值,即 primary color |
| home | Widget | 這個是一個Widget物件,用來定義當前應用打開時,所顯示的界面 |
| routes | Map<String,WidgetBuider> | 定義應用中頁面跳轉規則 |
| initialRoute | String | 初始化路由 |
| onGenerateRoute | RouteFactory | 路由回呼函式,當通過Navigator.of(context).pushNamed跳轉路由時,在routes查找不到時,會呼叫該方法 |
| onLocaleChanged | 當系統修改語言的時候,會觸發這個回呼 | |
| navigatorObservers | List | 導航觀察器 |
| debugShowMaterialGrid | bool | 是否顯示紙墨設計基礎布局網格,用來除錯UI的工具 |
| showPerformanceOverlay | bool | 顯示性能標簽 |
Scaffold
| 屬性名 | 型別 | 說明 |
|---|---|---|
| appBar | AppBar | 顯示在界面頂部的一個AppBar |
| body | Widget | 當前界面所顯示的主要內容 |
| floatingActionButton | Widget | 在Material Design中定義的一個功能按鈕 |
| persistentFooterButtons | List | 在固定在下方顯示的按鈕 |
| drawer | Widget | 側邊欄組件 |
| bottomNavigationBar | Widget | 顯示在底部的導航欄按鈕欄 |
| backgroundColor | Color | 背景顏色 |
| resizeToAvoidBottomPadding | bool | 控制界面內容body是否重新布局來避免底部被覆寫,比如當鍵盤顯示時,重新布局避免被鍵盤蓋住內容,默認值為true |
AppBar及SliverAppBar組件
| 屬性名 | 型別 | 默認值 |
|---|---|---|
| leading | Widget | null |
| title | Widget | null |
| actions | List | null |
| bottom | PreferredSize Widget | null |
| elevation | double | 4 |
| flexibleSpace | Widget | null |
| backgroundColor | Color | ThemeData.primaryColor |
| brightness | Brightness | ThemeData.primaryColorBrightness |
| iconTheme | IconThemeData | ThemeData.primaryIconTheme |
| textTheme | TextTheme | ThemeData.primaryTextTheme |
| centerTitle | bool | true |
介紹:
| 屬性名 | 說明 |
|---|---|
| leading | 在標題前面顯示的一個組件,在首頁通常顯示應用的logo;在其他界面通常顯示 |
| title | Toolbar中主要內容,通常顯示為當前界面的標題文字 |
| actions | 一個Widget串列,代表Toolbar中所顯示的選單,對于通常的選單,通常使用IconButton來表示,對于不太常用的選單通常使用PopupMenuButton來顯示為三點,點擊后彈出二級選單 |
| bottom | 通常是TabBar,用來在Toolbar標題下面顯示一個Tab導航欄 |
| elevation | 紙墨設計中組件的z坐標順序,對于可滾動的SliverAppBar,當SliverAppBar和內容同級的時候,該值為0,當內容咕噥的那個SliverAppBar變為ToolBar的時候,修改elevation |
| flexibleSpace | 一個顯示在AppBar下方的組件,高度和AppBar高度一樣,可以實作一些特殊的效果,該屬性通常在SliverAppBar中使用 |
| backgroundColor | 背景色 |
| brightness | AppBar的亮度,有白色和黑色兩種主題 |
| iconTheme | AppBar上圖示的顏色、透明度和尺寸資訊,默認值為ThemeData. primaryIcon Theme |
| textTheme | AppBar上的文字樣式 |
| centerTitle | 標題是否居中顯示,默認值根據不同的作業系統,顯示方式不一樣 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/262069.html
標籤:其他
上一篇:Mac m1恢復出廠設定
