1. 项目的目录结构
| 文件夹 | 描述 |
|---|---|
| android | android平台相关代码 |
| ios | ios平台相关代码 |
| lib | Flutter相关代码,主要编写的文件在这个目录下 |
| test | 存放测试代码 |
| pubspec.yaml | 配置文件,存放第三方库的依赖项 |
入口文件、入口方法
- lib文件夹中的main.dart文件为入口文件
- main方法是Dart的入口方法,runApp方法是Flutter的入口方法
-
2. 自定义组件
materialApp
封装了应用程序实现Material Design所需要的一些widget,一般作为顶层widget使用
3. 基础组件
状态管理组件
在Flutter中自定义组件其实就是一个类,这个类继承StatelessWidget/StatefulWidget。
- vscode 快捷键插件Awesome Flutter Snippets
无状态组件
StatelessWidget 无状态组件,状态不可变的Widget有状态组件
StatefulWidget 有状态组件,持有的状态可能在widget生命周期改变Text 组件
组件重要参数说明
| 名称 | 功能 |
|---|---|
| textAlign | 文本对齐方式(center、left、right、justfy) |
| textDirection | 文本方向(ltr从左至右、rtl从右至左) |
| maxLines | 文本显示最大行数 |
| overflow | 文本超出屏幕之后的处理方式(clip裁剪、fade渐隐、ellipsis省略号) |
| textScaleFactor | 文本显示最大倍数 |
| style | 字体的样式设置TextStyle |
TextStyle重要参数说明
| 名称 | 功能 |
|---|---|
| decoration | 文字装饰线 (none,lineThrough 删除线,overline 上划线,underline 下划线) |
| decorationColor | 文字装饰线颜色 |
| decorationStyle | 文字装饰线风格 (dashed,dotted 虚线,double 两根线,solid 一根线,wavy 波浪线) |
| wordSpacing | 单词间隙 |
| letterSpacing | 字母间隙 |
| fontStyle | 字体样式 |
| fontSize | 字体大小 |
| color | 字体颜色 |
| fontWeight | 字体粗细 |
Image 组件
Image.network 网络图片
| 名称 | 类型 | 说明 |
|---|---|---|
| alignment | Alignment | 图片的对齐方式 |
| color | 设置图片背景颜色,通常和colorBlendMode一起使用 | |
| colorBlendMode | BlendMode | 颜色混合 |
| fit | BoxFit | 控制图片的拉伸和挤压 |
| repeat | ImageRepeat | 图片平铺 |
Image.assets 本地图片
如何实现圆角以及实现圆形图片
- 通过Container 中的 decoration -> borderRadius
- clipOver
CircleAvatar (头像裁剪用的多)
// 通过Container 中的 decoration -> borderRadiusdecoration: BoxDecoration(borderRadius: BorderRadius.circular(150),image: DecorationImage(image: NetworkImage('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3593964987,1999043304&fm=15&gp=0.jpg',),fit: BoxFit.cover,),// borderRadius: BorderRadius.all(Radius.circular(150)))// clipOverchild: ClipOval(child: Image.asset('images/4.png',width: 150,height: 100,),)//CircleAvatar(backgroundImage: NetworkImage("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1129084263,3532636474&fm=26&gp=0.jpg"),)
AspectRatio 组件
AspectRatio根据设置调整子元素child的宽高比。
- AspectRatio首先会在布局限制条件允许的范围内尽可能的扩展,widget的高度是由宽度和比率决定的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。
- 如果在满足所有限制条件过后无法找到一个可行的尺寸,AspectRatio最终将会去优先适应布局限制条件,而忽略所设置的比率
Card 卡片组件
| 参数 | 说明 | | —- | —- | | margin | 外边距 | | shadowColor | 阴影颜色 | | shape | 阴影效果,默认阴影效果为圆角的长方形边 | | color | 背景颜色 | | child | 子组件 |
按钮组件
- ElevatedButton
- TextButton
- OutlinedButton 线框按钮
- IconButton 图标按钮
- ButtonBar 按钮组
FloatingActionButton 浮动按钮
// 普通按钮ElevatedButton(onPressed: () {},style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red),elevation: MaterialStateProperty.all(20.0),),child: Text('阴影按钮'),),// 文字按钮TextButton.styleFrom(shape: RoundedRectangleBorder(side: BorderSide(color: Colors.yellow,),),),// 线框按钮OutlinedButton(onPressed: () {},child: Container(height: 50,child: Text('outline'),),)// 图标按钮IconButton(icon: Icon(Icons.ac_unit_outlined),onPressed: () {},)// 按钮组ButtonBar(children: [ElevatedButton(onPressed: () {}, child: Text('按钮组1')),ElevatedButton(onPressed: () {}, child: Text('按钮组2')),ElevatedButton(onPressed: () {}, child: Text('按钮组3'))],)// 浮动按钮floatingActionButton: FloatingActionButton(onPressed: () {this.setState(() {this.currentIndex = 1;});},backgroundColor: this.currentIndex == 2 ? Colors.blue : Colors.red,child: Container(width: 100.0,height: 100.0,decoration: BoxDecoration(borderRadius: BorderRadius.circular(70),// color: Colors.blue,),child: Icon(Icons.add,),padding: EdgeInsets.all(8),// margin: EdgeInsets.only(top: 10.0),),),floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
表单组件
TextField 文本框组件
- Checkbox、CheckboxListTile 多选框组件
- Radio、RadioListTile
- 日期组件
- 自带组件
- 第三方组件
-
弹框组件
showDialog
AlertDialog
showDialog(context: context,builder: (context) {return AlertDialog(title: Text('删除'),content: Text('确认取消吗'),actions: [ElevatedButton(onPressed: () {Navigator.pop(context, 'cancel');},child: Text('取消'),),ElevatedButton(onPressed: () {Navigator.pop(context, 'ok');},child: Text('确定'),)],);},);
SimpleDialog
showDialog(context: context,builder: (context) {return SimpleDialog(title: Text('选择内容'),children: [SimpleDialogOption(child: Text('1'),),SimpleDialogOption(child: Text('2'),),SimpleDialogOption(child: Text('3'),),SimpleDialogOption(child: Text('4'),)],);});
showModalBottomSheet
showModalBottomSheet(context: context,builder: (context) {return Container(height: 200.0,child: Column(children: [ListTile(title: Text('分享一'),),Divider(color: Colors.black),ListTile(title: Text('分享二'),),Divider(color: Colors.black),ListTile(title: Text('分享三'),)],),);},);
Fluttertoast.showToast
import 'package:fluttertoast/fluttertoast.dart';Fluttertoast.showToast(msg: '提示信息',toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM,timeInSecForIos: 1,backgroundColor: Colors.red,);
自定义Dialog
sMaterial Design布局结构的基本实现,此类提供了用于显示drawer、snackbar和底部sheet的API
import 'package:flutter/material.dart';
BottomNavigationBar 底部导航组件
| 参数 | 说明 | | —- | —- | | currentIndex | 默认选中第几个 | | onTap | 点击回调方法 | | iconSize | icon大小 | | fixedColor | 选中的颜色 | | type | BottomNavigationBarType.fixed 可以有多个按钮 BottomNavigationBarType.shifting | | items | LIst BottomNavigationBarItem
底部导航条按钮集合 |
AppBar 顶部导航组件
| 参数 | 说明 |
|---|---|
| centerTitle | 无论安卓、ios都居中显示 |
| leading | 头部导航前面展示的组件 |
| actions | 头部导航后面展示的组件 |
| bottom | 自定义组件 |
TabBar 组件
| 参数 | 说明 |
|---|---|
| tabs | 显示的标签内容,便是Tab对象,也可以是其他的widget |
| controller | TabController对象 (结合SingleTickerProviderStateMixin) |
| isScrollable | 是否可以滚动 |
| indicatorColor | 指示器的颜色 |
| indicatorWeight | 指示器高度 |
| indicatorPadding | 底部指示器的高度 |
| indicator | 指示器decoration,例如边框等 |
| indicatorSize | 指示器大小计算方式 TabBarIndicatorSize.label 跟文字等宽 TabBarIndicatorSize.tab 跟tab等宽 |
| labelColor | 选中的label的颜色 |
| labelStyle | 选中的label的style |
| labelPadding | 每个label的padding值 |
| unselectedLabelColor | 未选中的label的颜色 |
| unselectedLabelStyle | 未选中的label的style |
Container 组件
组件重要参数说明
| 名称 | 功能 |
|---|---|
| alignment | topCenter 顶部居中对齐 topLeft 顶部左对齐 topRight 顶部右对齐 center 水平垂直居中对齐 centerLeft 垂直居中水平居左对齐 centerRight 垂直居中水平居右对齐 bottomLeft 底部左对齐 bottomRight 底部右对齐 |
| transform | 矩阵变换 |
| decoration | 设置背景颜色、边框颜色 |
Padding
| 名称 | 说明 |
|---|---|
| padding | padding EdgeInsets设置填充的值 |
| child | 自组件 |
5. 可滚动组件
ListView
水平列表、垂直列表
- 列表参数
| 名称 | 类型 | 说明 |
| —- | —- | —- |
| scrollDirection | Axis | Axis.horizontal 水平列表
Axis.vertical 垂直列表 | | padding | EdgeInsetsGeometry | 内边距 | | resolve | bool | 组件反向排序 | | children | List[Widget] | 列表元素 |
ListView(scrollDirection: Axis.horizontal,padding: EdgeInsets.all(10),children: <Widget>[ListTile(title: Text("标题"),subtitle: Text("二级标题"),leading: Icon(Icons.home),// tileColor: Colors.red,selectedTileColor: Colors.yellow),ListTile(title: Text("标题"),subtitle: Text("二级标题"),leading: Image.network('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3593964987,1999043304&fm=15&gp=0.jpg'),trailing: Icon(Icons.offline_bolt, color: Colors.red, size: 28.0),)])
-
动态列表
map、for 等方法
-
GridView
网格列表
GridView.count | 名称 | 类型 | 说明 | | —- | —- | —- | | children | List[Widget] | 列表元素 | | crossAxisCount | Int | 一行的Widget数量 | | mainAxisSpacing | Double | 垂直Widget之间的间距 | | crossAxisSpacing | Double | 水平Widget之间的间距 | | childAspectRatio | Double | Widget的宽高比 |
GridView.builder | 名称 | 类型 | 说明 | | —- | —- | —- | | itemCount | Int | 列表数量 | | gridDelegate | SliverGridDelegateWithFixedCrossAxisCount | 列表样式之类的写在其中 | | itemBuilder | Widget | Widget元素 |
6. 布局类组件
线性布局
Row 水平布局组件
| 名称 | 说明 |
|---|---|
| mainAxisAlignment | 主轴的排序方式 |
| crossAxisAlignment | 次轴的排序方式 stretch(次轴高度填满)、center、start、end |
| children | 组件子元素 |
Column 垂直布局组件
| 名称 | 说明 |
|---|---|
| mainAxisAlignment | 主轴的排序方式 |
| crossAxisAlignment | 次轴的排序方式 stretch(次轴高度填满)、center、start、end |
| children | 组件子元素 |
弹性布局
Expanded
web端的flex布局
| 名称 | 说明 |
|---|---|
| flex | |
| child | 子组件 |
对齐与相对定位 Stack 、Align
// Stack 和 AlignStack(children: [Align(alignment: Alignment.topCenter,child: Icon(Icons.ac_unit,color: Colors.white,),),Align(alignment: Alignment.center,child: Icon(Icons.sanitizer,color: Colors.white,),),Align(alignment: Alignment.bottomCenter,child: Icon(Icons.east,color: Colors.white,),),],)
层叠布局 Stack 、Positioned
- 与Web中的绝对定位概念类似
stack参数说明
| 名称 | 说明 |
|---|---|
| alignment | 配置所有子元素的显示位置 |
| children | 自组件 |
// Stack 和 PositionedStack(children: [Positioned(left: 0,top: 0,child: Icon(Icons.ac_unit,color: Colors.white,),),Positioned(top: 0,right: 0,child: Icon(Icons.sanitizer,color: Colors.white,),),])
流式布局 Wrap、Flow
Wrap
warp实现流式布局,单行的Wrap和Row表现基本一致,单列的Wrap则跟Column表现一致。但Row和Column都是单行单列的,Wrap则突破了这个限制,mainAxis上空间不足时,则向crossAxis上扩展显示。
| 属性 | 说明 |
|---|---|
| direction | 主轴方向,默认水平 |
| alignment | 主轴的对齐方式 |
| runAlignment | 纵轴的对齐方式 |
| spacing | 主轴方向上的间距 |
| runSpacing | 纵轴方向上的间距 |
| children | 子组件 |
7. 路由
基本路由以及参数传递
// 基本路由Navigator.of(context).push(MaterialPageRoute(builder: (context) {return Search();},),),
命名路由以及参数传递
// 命名路由Navigator.pushNamed(context, '/search')// 不传惨routes: {'/search': (context) => Search(),'/list': (context) => List(),},// 传参数onGenerateRoute: (RouteSettings settings) {final name = settings.name;final Function pageContentBuilder = this.routes[name];Route route;if (pageContentBuilder != null) {if (settings.arguments != null) {route = MaterialPageRoute(builder: (context) {return pageContentBuilder(context, arguments: settings.arguments);},);}} else {route = MaterialPageRoute(builder: (context) {return pageContentBuilder(context);},);}return route;},);
路由替换
Navigator.pushReplacementNamed(context,'/search',arguments: {"title": "参数传递",},)
返回根路由
Navigator.of(context).pushAndRemoveUntil(new MaterialPageRoute(builder: (context) => Tabs(currentIndex: 1),),(route) => route == null)
8. 接口请求
- json字符串和Map类型的转换
- import ‘dart:convert’;
- json.encode
- json.decode
请求数据 http
import 'package:http/http.dart' as http;var httpUrl = '';var data = await http.get(httpUrl);var data = await http.post(httpUrl,// headers: {'Content-Type': 'application/json; charset=utf-8'},body: json.encode({'Phone': '18116462666', 'Password': '123456789'}),);
请求数据 dio
import 'package:dio/dio.dart';var httpUrl = '';var dio = Dio();Response result = await dio.get(httpUrl);Response result = await dio.post(httpUrl, data: data);
