-
变量
# 可以使用var或者类型定义变量 main() { var num = 123; print(num); // 输出123 String a = "zhangsan"; int b = 5678; print(a); // 输出: "zhangsan" print(b); // 输出: 5678 }
-
常量
# 使用final或者const定义常量 main() { const num = 456; print(num); final a = new DateTime.now(); // 注意,这里使用const会报错 print(a) }
-
Numbers(数值):
- int
- double
- 详细代码请看:/dart/数据类型/Number.dart
-
Strings(字符串):
-
Booleans(布尔):
-
List(数组):
- 在dart中,数组是列表对象,所以大多数人只称他们为列表
- 详细代码请看:/dart/数据类型/List.dart
-
Maps(字典):
- 通常来说,Map是一个键值对相关的对象。键和值可以是任何类型的对象,每个键只出
- 详细代码请看:/dart/数据类型/Map.dart
-
数据类型的判断:
-
赋值运算符
-
关系运算符
-
逻辑运算符
-
算术运算符
-
if else
-
switch case
-
String转int
- int.parse()
String a = '123'; int b = int.parse(a); print(b);
- int.parse()
-
int 转String
- toString()
int c = 22; String d = c.toString(); print(d);
- toString()
-
double跟与String的转换跟int一样
-
for循环
-
while循环
-
List
-
Map
-
Set
-
集合里面的循环
-
方法的定义 变量 方法的作用域
-
方法传参 、默认参数、可选参数、命名参数 、方法作为参数
-
箭头函数、函数的相互调用
-
匿名方法、自执行方法、方法的递归
-
Dart面向对象的介绍以及Data内置对象
-
Dart中创建义类使用类
-
Dart中自定义类的默认构造函数
-
Dart中自定义类的命名构造函数
-
Dart中把类单独抽离成一个模块
-
Dart中的私有方法和私有属性
-
类中的getter和setter修饰符的用法
-
类中的初始化列表
-
静态类
-
类的继承
-
Dart中的对象操作符
- ? 条件运算符(了解)
- as 类型转换
- is 类型判断
- .. 级联操作(连缀)(记住)
- 详细代码请看:/dart/类/类的继承/Dart中的对象操作符.dart
-
Dart类的继承-简单继承
-
类的继承-super关键词的使用-实例化自类给父类构造函数传参
-
类的继承-实例化自类给命名构造函数传参
-
类的继承-覆写父类的方法
-
自类里面调用父类的方法
-
-
抽象类和接口
-
Dart中的抽象类
-
Dart中多态
-
接口
-
接口-文件分离
-
Dart中implements实现多个接口
-
-
mixins混入
-
泛型
-
Dart中导入自己本地库
-
导入系统内置库math库
-
安装JDK,推荐1.8版本
-
安装Android Studio
- 下载地址:https://developer.android.google.cn/studio
- 安装完毕后,在plugins里搜索下载Flutter和Dart安装
- 注意:最好是用手机热点,电信网下载,不然插件市场无法搜索
-
下载配置 Flutter Sdk
-
配置国内镜像的环境变量
- FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
- PUB_HOSTED_URL: https://pub.flutter-io.cn
-
在命令行输入flutter doctor,出现全是√的时候就完成了
-
详细文档请看:/flutter/01环境搭建/Flutter介绍-Flutter、Windows、Android环境搭建.pdf
- 在android studio中新建flutter项目后,把项目放到vscode中,输入命令flutter run即可
-
helloworld案例,详细代码请看:/flutter/02最简单的例子/helloworld.dart
-
MaterialApp&Scaffold完整的组件, 详细代码请看:/flutter/02最简单的例子/MaterialApp&Scaffold.dart
-
详细文档请看:/flutter/02最简单的例子/Flutter目录结构介绍、入口、自定义Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件.pdf
-
圆角图片
-
使用borderRadius来制作圆角图片, 详细代码请看:/flutter/04Image图片/圆角图片/用borderRadius做圆角图片.dart
-
使用ClipOval做圆角图片, 详细代码请看:/flutter/04Image图片/圆角图片/ClipOval做圆角图片.dart
-
-
本地图片
-
在根目录下新建images文件夹,并在里面新建2.0x(表示二倍图), 3.0x(三倍图)文件夹,把图片分别放进去
-
在根目录下的pubspec.yaml,找到assets:配置图片
flutter: assets: - images/a.jpg - images/2.0x/a.jpg - images/3.0x/a.jpg
-
-
垂直列表
-
垂直图片列表
-
水平列表
-
水平图片列表
-
使用循环方式遍历列表
-
使用ListView.builder遍历列表
-
crossAxisCount一行多列, 详细代码请看:/flutter/07GridView网格列表/crossAxisCount一行多列.dart
-
列间距
- mainAxisSpacing和crossAxisSpacing 详细代码请看:/flutter/07GridView网格列表/mainAxisSpacing和crossAxisSpacing间距.dart
-
布局练习,一行两列,详细代码请看:/flutter/07GridView网格列表/test.dart
-
使用GridView-builder循环列表, 详细代码请看:/flutter/07GridView网格列表/GridView-builder循环列表.dart
-
详细文档请看:/flutter/07GridView网格列表/flutter-GridView组件以及动态GridView.pdf
-
Padding组件,用于组件间的padding值设定
-
Row组件,水平布局
-
Column组件,垂直布局
-
Expanded组件,flex,三个盒子,分别占1分,2分,1分
-
练习
-
详细文档请看:/flutter/08Padding、Row、Column、Expanded/flutter页面布局Paddiing、Row、Column、Expanded组件详解.pdf
-
只使用alignment,stack里的所有内容位置都变化
-
stack结合Align组件
-
stack结合Posited组件
-
详细文档请看:/flutter/09Stack层叠组件/Stack层叠组件-Stack与Align、Stack与Positioned实现定位布局.pdf
-
AspectRatio宽高比组件,相对于父元素
-
Card组件
-
练习
-
详细文档请看:/flutter/10AspectRatio宽高比组件与Card组件/Flutter-AspectRatio、Card卡片组件.pdf
-
横轴的换行
-
纵轴的换行
-
路由跳转,使用Navigator.push
-
路由传值
-
命名路由跳转,使用Navigator.pushNamed
-
命名路由跳转传值,使用onGenerateRoute
-
在命名路由跳转传值基础上进行封装,抽离路由。production.dart包含有状态组件的传值
-
详细文档请看:/flutter/14路由、路由跳转、路由跳转传值、命名路由、命名路由传值/Flutter中的普通路由、普通路由传值、命名路由、命名路由传值.pdf
-
使用Navigator.pushNamed这种跳转,返回的时候只能返回上一级
-
使用Navigator.pushReplacementNamed跳转,可以返回到第一级
-
普通路由跳转,返回到第一级,使用Navigator.pushAndRemoveUntil
-
普通路由跳转,返回到指定目录
-
详细文档请看:/flutter/15替换路由/Flutter中的路由-pushReplacementNamed路由替换、pushNamedAndRemoveUntil返回到根路由.pdf
-
设置导航栏的文字,图标
-
顶部导航栏设置选项卡
-
使用tabController的好处是,可以给选项卡添加事件 详细代码请看:/flutter/16自定义头部导航栏/导航栏选项卡2.dart
-
有底部导航栏的时候增加顶部选项卡
-
使用tabController渲染顶部导航栏,使用tabController的好处是,可以给选项卡添加事件
-
详细文档请看:/flutter/16自定义头部导航栏/Flutter-AppBar自定义顶部导航按钮、图标颜色以及TabBar定义顶部Tab切换.pdf
-
DrawHeader抽屉头部自定义组件
-
UserAccountsDrawerHeader头部组件
-
抽屉中点击事件,跳转,使用onTap
-
RaisedButton:凸起的按钮,其实就是 Material Design 风格的 Button
-
FlatButton:扁平化的按钮
-
OutlineButton:线框按钮
-
IconButton:图标按钮
-
ButtonBar:按钮组
-
FloatingActionButton:浮动按钮
-
详细文档请看:/flutter/18按钮组件/Flutter-FloatingActionButton结合底部tab实现中间凸起按钮.pdf
-
布局,详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/demo.dart
-
设置初始值以及修改, 详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/表单的赋值和修改.dart
-
checkbox布局和修改值, 详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/checkbox.dart
-
CheckboxListTile,复选框列表,详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/CheckboxListTile.dart
-
Radio布局和修改值,详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/Radio.dart
-
RadioListTile单选列表布局,详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/RadioListTile.dart
-
Switch开关组件,详细代码请看:/flutter/19TextField表单组件、Checkbox复选框、Radio单选框/Switch.dart
-
flutter日期间的相互转换
- 获取时间:DateTime.now();
var now = DateTime.now(); print(now); // 获取当前时间 2020-02-22 18:51:27.642596
- 时间转换为时间戳:DateTime.now().millisecondsSinceEpoch
var now = DateTime.now(); print(now.millisecondsSinceEpoch); // 日期转换为时间戳 1582368687642
- 时间戳转换为时间: DateTime.fromMillisecondsSinceEpoch()
print(DateTime.fromMillisecondsSinceEpoch(1582368144393)); // 将时间戳转换为时间 2020-02-22 18:42:24.393
-
时间的转换
- 使用第三方库dateformat
-
在pubspec.yaml中配置dateformat
dependencies: date_format: ^1.0.8
-
引入包并使用
import 'package:date_format/date_format.dart'; print(formatDate(DateTime.now(), [yyyy, '-', mm, '-', dd]));
-
flutter自带日期控件,包括修改值
-
flutter自带时间控件,包括修改值
-
flutter设置国际化
-
配置flutter_localizations依赖
找到pubspec.yaml配置flutter_localizations dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter
-
导入国际化的包 flutter_localizations
import 'package:flutter_localizations/flutter_localizations.dart';
-
设置国际化
void main() { runApp( new MaterialApp( title: 'app', theme: new ThemeData( primaryColor: Colors.white, ), home: new MyLoginWidget(), localizationsDelegates: [ //此处 GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: [ //此处 const Locale('zh', 'CH'), const Locale('en', 'US'), ], ), ); }
-
要显示中文的控件设置
_showDatePicker() async{ var date =await showDatePicker( context: context, initialDate: _datetime, firstDate:DateTime(1900), lastDate:DateTime(2050), locale: Locale('zh'), ); if(date==null) return; print(date); setState(() { _datetime=date; }); }
-
-
第一步: 在pubspec.yaml配置flutter_cupertino_date_picker
dependencies: flutter_cupertino_date_picker: ^1.0.12
-
第二步:导入控件,在Home.dart中引入包
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
-
结合文档,写入代码:
DatePicker.showDatePicker( context, pickerTheme: DateTimePickerTheme( showTitle: _showTitle, confirm: Text('确定', style: TextStyle(color: Colors.red)), cancel: Text('取消', style: TextStyle(color: Colors.cyan)), ), minDateTime: DateTime.parse(minDate), maxDateTime: DateTime.parse(maxDate), initialDateTime: _dateTime, dateFormat: _format, locale: DateTimePickerLocale.zh_cn, onClose: () => print("----- onClose -----"), onCancel: () => print('onCancel'), onChange: (dateTime, List<int> index) { setState(() { _dateTime = dateTime; }); }, onConfirm: (dateTime, List<int> index) { setState(() { _dateTime = dateTime; }); }, );
-
详细文档请看:https://pub.dev/packages/flutter_cupertino_date_picker
-
该控件的github地址:https://github.com/dylanwuzh/flutter-cupertino-date-picker
-
第一步: 在pubspec.yaml配置flutter-swiper
dependencies: flutter_swiper: ^1.1.6
-
第二步:导入控件,在demo.dart中引入包
import 'package:flutter_swiper/flutter_swiper.dart';
-
结合文档,写入代码:
body: new Swiper( itemBuilder: (BuildContext context,int index){ return new Image.network("http://via.placeholder.com/350x150",fit: BoxFit.fill,); }, itemCount: 3, pagination: new SwiperPagination(), control: new SwiperControl(), );
- AlertDialog
- SimpleDialog
- showModalBottomSheet
- flutter-toast
- 详细代码请看:/flutter/23弹窗组件AlertDialog、SimpleDialog、showModalBottomSheet、flutter-toast第三方库/main.dart
-
其实就是继承Dialog类
-
设置定时器Timer.periodic,使用前需要引入 import 'dart:async';
-
Map与json之间的转换
-
Map转换为json,使用json.encode(data)
import 'dart:convert'; var mapData = {"name": "张三", "age": "20"} var strData = '{"name": "张三", "age": "20"}' print(json.encode(mapData))
-
json转换为Map,使用json.decode(data)
import 'dart:convert'; var mapData = {"name": "张三", "age": "20"} var strData = '{"name": "张三", "age": "20"}' print(json.decode(strData))
-
-
http库get获取数据
-
http库post获取数据
-
下载安装provide
dependencies: provide: ^1.0.2
-
引入
import 'package:provide/provide.dart';
-
创建provide
新建一个provide文件夹,然后再里边新建一个demo.dart 文件.代码如下: import 'package:flutter/material.dart'; class Demo with ChangeNotifier{ int count = 0; add() { count ++; notifyListeners(); // 通知相关组件,内容改了 } }
-
将状态放到最顶层main.dart中
import 'package:provide/provide.dart'; import './provide/counter.dart'; void main(){ var demo = Demo(); var providers = Providers(); providers..provide(Provider<Demo>.value(demo)); runApp( ProviderNode(child: MyApp(), providers: providers) ); }
-
在category/index.dart中获取状态,使用Provide的builder方法
class Number extends StatelessWidget { @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(top: 200), child: Provide<Demo>( builder: (context, child, item){ return Text('${item.count}'); } ) ); } }
-
修改状态,使用provide的value方法调用写好的add
class MyButton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( child: RaisedButton( onPressed: (){ Provide.value<Demo>(context).add(); }, child: Text('递增'), ), ); } }
-
AutomaticKeepAliveClientMixin这个Mixin就是Flutter为了保持页面设置的。哪个页面需要保持页面状态,就在这个页面进行混入。
-
使用条件:
- 使用的页面必须是StatefulWidget,如果是StatelessWidget是没办法办法使用的。
- 其实只有两个前置组件才能保持页面状态:PageView和IndexedStack。
- 重写wantKeepAlive方法,如果不重写也是实现不了的。
-
使用步骤:
-
需求是记住首页的状态,不要让他每次切换都调接口,在home/index.dart中
混入AutomaticKeepAliveClientMixin,重写wantKeepAlive方法 class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true;
-
在他的上层通过IndexedStack包裹起来(pages/index_page.dart)
body: IndexedStack( index: currentIndex, children: tabBodies, ),
-
-
使用Provider状态管理,类似于vuex和redux
-
使用步骤:
-
在pubspec.yaml中下载provide
dependencies: provide: ^1.0.2
-
新建provider文件夹,新建home.dart,写入以下代码:
import 'package:flutter/material.dart'; class HomeData with ChangeNotifier { Map dataSource = {}; getHomeData(data){ dataSource = data; notifyListeners(); } }
-
在根目录main.dart下,注册Provider ``` import 'package:provide/provide.dart'; import 'package:app/provide/home.dart';
void main(){ var home =HomeData(); var providers = Providers(); providers ..provide(Provider.value(home)); runApp(ProviderNode(child:Myapp(),providers:providers)); } ```
-
获取Provier里的值:使用Provide.value方法
import 'package:provide/provide.dart'; import 'package:app/provide/home.dart'; Provide.value<HomeData>(context).dataSource['tabs'][0]['info']['tooltip'];
-
修改provider里的值:还是使用Provide.value方法
import 'package:provide/provide.dart'; import 'package:app/provide/home.dart'; Provide.value<HomeData>(context).getHomeData(snapshot.data['data']); // 给provide赋值
-
-
下载flutter_easyrefresh和flutter_localizations
dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter flutter_easyrefresh: ^2.0.9
-
在页面中引入包
import 'package:flutter_easyrefresh/easy_refresh.dart';
-
使用步骤:
1. 定义控制器变量 EasyRefreshController _controller; 2. 初始化 void initState() { super.initState(); _controller = EasyRefreshController(); // 初始化控制器 } 3. 使用EasyRefresh()包裹你的列表,设置onLoad和onRefresh方法即可
-
国际化:
在根路径main.dart中,引入: import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; 加入以下代码即可: localizationsDelegates: [ GlobalEasyRefreshLocalizations.delegate, GlobalCupertinoLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate ], supportedLocales: [ Locale('zh', 'CN'), ],
-
配置APP的图标
-
想配置APP的图片,你需要找到下面的目录:项目根目录/android/app/src/main/res/,进去之后,会看到mipmap-hdpi、mipmap-mdpi、mipmap-xhdpi、mipmap-xxhdpi、mipmap-xxxhdpi这5个文件夹,将你的图标放进去,注意图标的名称必须相同
-
找到/android/app/src/main/AndroidManifest.xml文件,可以配置APP的名称、图标
android:label="flutter_app" //配置APP的名称,支持中文 android:icon="@mipmap/ic_launcher" //APP图标的文件名称
-
-
生成keystore
- 在项目当前目录下输入命令: keytool -genkey -v -keystore C:/Users/ASUS/Desktop/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
-
在Android文件夹下,新建key.properties,并写入前面的密码
storePassword=123123 keyPassword=123123 keyAlias=key storeFile=C:/Users/ASUS/Desktop/key.jks
-
找到android/app/build.gradle文件,修改此文件
-
以上都搞定之后,执行flutter build apk
-
如果打包成功了,会在build/app/outputs/apk/release文件夹下,生成app-release.apk,然后在当前目录下执行flutter install就打包完成
-
详细文档请看:https://blog.csdn.net/duo_shine/article/details/81382757
- 使用插件:flutter_screenutil
-
下载:
在pubslipec.yaml里: dependencies: flutter_screenutil: ^1.0.2
-
引入:
import 'package:flutter_screenutil/flutter_screenutil.dart';
-
使用:
1.在根组件初始化设计尺寸:ScreenUtil.init(context, width: 750, height: 1334, allowFontScaling: true); 2. 在需要的地方,使用setHeight(), setWisth()设置宽高 height: ScreenUtil().setHeight(333),
-
-
如何去掉appBar的底部阴影 ``` elevation: 0 加上这个属性就可以去掉底部的阴影
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('我的'), backgroundColor: Colors.deepOrange, elevation: 0, //去掉Appbar底部阴影 ), body: Column( children: [ Row( children: [MineHead()], ) ], )); } ```
-
如何给appbar添加颜色渐变
使用flexibleSpace属性 appBar: AppBar( flexibleSpace: Container( // 设置渐变色 decoration: BoxDecoration( gradient: LinearGradient(colors: [ Color.fromRGBO(253, 99, 52, 1), Color.fromRGBO(253, 52, 52, 1) ])), ), )
-
实现以下布局
# 布局思路 * appBar是第一行,搜索框放到body里的,tabbar和tabbarView都在body里,而不是在appBar里 # 注意 TabBarView必须要求高度要确定,结合Expanded组件一起使用,不然会报错 # 导航有滚动是设置isScrollable: true,
-
tabBar的动态渲染及循环
-
注意:
-
使用FutureBuilder异步渲染组件的时候,不能在组件或者build中使用setState会报错
-
在获取到tab的数据后,他是个数组,循环只能用for循环,不能用map,因为数据返回的数组不是List,而是List
-
使用FutureBuilder的时候,tabBar的tabController不要定义在initState中,而是把它定义在FutureBuilder中
body: FutureBuilder( future: request('home', 'post'), builder: (context, snapshot) { if (snapshot.hasData) { // 处理数据 var tabsArr = snapshot.data['data']['tabs']; // 类型不是List<Map>,是List<dynamic> // 初始化tabBar的控制 _tabController = new TabController(length: tabsArr.length, vsync: this); _tabController.addListener(() { print(_tabController.index); }); return Column( children: <Widget>[ SearchComponent(), Container( decoration: BoxDecoration( gradient: LinearGradient(colors: [ Color.fromRGBO(253, 99, 52, 1), Color.fromRGBO(253, 52, 52, 1) ])), child: TabBar( isScrollable: true, controller: _tabController, tabs: this._getTabsData(tabsArr)), ), // 渲染tab _getTabsData(tabsArr) { List<Widget> list = new List(); for(int i=0; i<tabsArr.length;i++) { // 只能用for循环 list.add(Tab(text: tabsArr[i]['title'])); } print(list); return list; }
-
-
详细代码请看:/flutter/布局例子/tabBar的动态渲染及循环、FutureBulder的用法/main.dart
-
-
实现以下布局