Flutter是Google開(kāi)發(fā)的一套全新的跨平臺(tái)、開(kāi)源UI框架(本質(zhì)上就是sdk)。 支持iOS、Android系統(tǒng),并且是Fuchsia系統(tǒng)的默認(rèn)開(kāi)發(fā)套件。桌面和web上的支持也都在實(shí)驗(yàn)中。
Flutter特點(diǎn):跨平臺(tái)(Flutter是Fuchsia的開(kāi)發(fā)框架,同時(shí)支持Android、IOS),媲美原生性能,熱重載(目前不支持熱更新,但已加入2019工作計(jì)劃)。
其官方編程語(yǔ)言為Dart,熟悉Dart語(yǔ)言。
入門網(wǎng)站:Flutter中文網(wǎng) Flutter官網(wǎng)(英文)
1、工程基礎(chǔ)簡(jiǎn)介
1.1 Dart導(dǎo)包規(guī)則
(1)導(dǎo)包dart庫(kù)里面的包
import 'dart:html';
(2)導(dǎo)入pubspec.yaml 的dependencies依賴的包
import 'package:test/test.dart';
(3)導(dǎo)入路徑包,base為flutter根目錄
import 'package:base/components/swiper.dart';
(4)只導(dǎo)入foo
import 'package:lib1/lib1.dart' show foo;
(5)Im除了foo都導(dǎo)入
import 'package:lib2/lib2.dart' hide foo;
(6)包里面存在標(biāo)識(shí)符沖突
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
(7)延遲加載(懶加載)允許應(yīng)用程序在需要時(shí)加載庫(kù)。以下是一些您可能使用延遲加載的情況:
? ?減少應(yīng)用程序的初始啟動(dòng)時(shí)間。
? ?例如,執(zhí)行A / B測(cè)試 - 試用算法的其他實(shí)現(xiàn)。
? ?加載很少使用的功能,例如可選的對(duì)話框。
import 'package:greetings/hello.dart' deferred as hello;
1.2 工程配置文件:
Flutter項(xiàng)目中的pubspec.yaml文件相當(dāng)于Android項(xiàng)目中的gradle文件,項(xiàng)目的信息以及依賴在此文件中聲明。依賴包由pub包倉(cāng)庫(kù)管理:https://pub.dartlang.org/ ,未發(fā)布在pub包倉(cāng)庫(kù)的插件可以使用本地文件路徑,甚至可以直接使用git項(xiàng)目地址。 參考:https://flutterchina.club/using-packages/
依賴沖突:用any來(lái)解決,會(huì)找到最合適的不沖突版本,再到 pubspec.lock中找到版本號(hào)替換,最終不要直接用any,是個(gè)風(fēng)險(xiǎn)。
#name很重要,如果修改了name所有的dart的文件的import前引用的本地的文件啊的包名都需要修改
name: flutterdemo
description: A new Flutter application.
dependencies:
flutter:
sdk: flutter
#添加依賴packages
cupertino_icons: ^0.1.2
english_words: ^3.1.0
# image_picker: ^0.4.8
dev_dependencies:
flutter_test:
sdk: flutter
#啟用國(guó)際化
flutter_localizations:
sdk: flutter
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
#添加資源,不單單是圖片,images是個(gè)和pubspec.yaml配置文件同級(jí)的目錄,如果不同級(jí),需要添加..
assets:
- images/park.jpg
- images/lake.jpg
- images/touxiang.jpg
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#字體設(shè)置
fonts:
- family: Schyler
fonts:
- asset: fonts/Schyler-Regular.ttf
- asset: fonts/Schyler-Italic.ttf
style: italic
- family: Trajan Pro
fonts:
- asset: fonts/TrajanPro.ttf
- asset: fonts/TrajanPro_Bold.ttf
weight: 700
2、關(guān)于MaterialApp和Scaffold:
Flutter提供了兩套不同風(fēng)格的UI控件,分別是類Android風(fēng)格的MaterialApp和類IOS風(fēng)格的CupertinoApp。兩種風(fēng)格下面的widget不能完全通用,且Material風(fēng)格的widget數(shù)量要多一些。
~ MaterialApp是Flutter提供給Android的一個(gè)基礎(chǔ)widget,采用了材料設(shè)計(jì)風(fēng)格。
經(jīng)過(guò)實(shí)踐,MaterialApp全局最好只有一個(gè),作為主界面,app的主題、主頁(yè)等全局設(shè)置可以在此定義。
最初按照官網(wǎng)教程每個(gè)page我都返回的MaterialApp,顯示是沒(méi)什么問(wèn)題,因?yàn)槎际莣idget,但是會(huì)出現(xiàn)卡頓和其他界面上的問(wèn)題,大家可以自己試一下。
~ 子頁(yè)面直接返回Scaffold,Scaffold是MaterialApp的布局實(shí)現(xiàn),提供了appbar,floatingActionButton,drawer,bottomNavigationBar等MD風(fēng)格的控件api。
Flutter默認(rèn)會(huì)在debug模式下在右上角顯示水印,去除方式:
debugShowCheckedModeBanner: false
3、自定義控件。
Flutter框架給我們提供了StatelessWidget和StatefulWidget兩個(gè)抽象類,用于自定義控件。
(1)StatelessWidget是‘‘無(wú)狀態(tài)控件’’,不可變狀態(tài)控件,通過(guò)構(gòu)建其他控件來(lái)描述用戶界面的一部分。必須實(shí)現(xiàn)build方法,返回一個(gè)widget對(duì)象。 Icon、 IconButton, 和Text等都是無(wú)狀態(tài)widget, 他們都是 StatelessWidget的子類。
(2)StatefulWidget 是動(dòng)態(tài)的. 用戶可以和其交互 (例如輸入一個(gè)表單、 或者移動(dòng)一個(gè)slider滑塊),或者可以隨時(shí)間改變 (也許是數(shù)據(jù)改變導(dǎo)致的UI更新).Checkbox, Radio, Slider, Form, 和TextField 都是 stateful widgets, 他們都是 StatefulWidget的子類。
(3)自定義Widget:繼承StatefulWidget,并重寫createState()方法,返回一個(gè)State對(duì)象。
自定義無(wú)狀態(tài)的widget:
class RedBoard extends StatelessWidget {
const RedBoard({ Key key }) : super(key: key);
@override
Widget build(BuildContext context) {
return new Container(
color: Colors.red
);
}
}
自定義可變狀態(tài)的widget:
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return (new Text(wordPair.asPascalCase));
}
}
(4)繼承自CustomPaint畫控件
Flutter也可以像Android中繼承View的方式來(lái)繪制控件,通過(guò)繼承CustomPaint類來(lái)實(shí)現(xiàn),具體用法此處略。
4、TextField樣式
decoration: new InputDecoration(
hintText: 'input name to search',
border: InputBorder.none
)
去掉下邊框。
外面套上Container,加上裝飾實(shí)現(xiàn)四面邊框效果
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.green, width: 1.0),
borderRadius: BorderRadius.circular(4)),
注意:
在decoration中加了color屬性,在Container中就不能加color屬性,否則會(huì)出錯(cuò)。
TextField坑:
軟鍵盤resize窗口,解決方式:
In your `Scaffold`, set `resizeToAvoidBottomPadding` property to `false`.
preprefixIcon和suffixIcon如果使用系統(tǒng)提供的svg資源,需要指定顏色,不然在獲取焦點(diǎn)時(shí)會(huì)變成不可見(jiàn)狀態(tài)。
5、ListView
ListView的使用可以參考此文:https://blog.csdn.net/hao_m582/article/details/84112278
如果與其他widget放在同一個(gè)Column中,ListView外加Expanded才能正常顯示。
可以用ListView作為滾動(dòng)塊,相當(dāng)于android中的ScrollView效果,但是子view不是寫在widget中,而是直接寫在ListView的children屬性中,如:
//...
body: new ListView(
children: [
new Image.asset(
'images/lake.jpg',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
),
titleSection,
buttonSection,
textSection,
],
),
//..
6、加載圖片與控件縮放
需要在pubspec.xml中配置圖片路徑,可以看上段代碼片段。
assets:
- images/park.jpg
- images/lake.jpg
- images/touxiang.jpg
其中images文件夾放在工程的根目錄。加載圖片可以直接使用AssertImage類,也可以使用Image.asset方法。
經(jīng)過(guò)查找,flutter不完全支持svg,xml格式的VectorDrawable在flutter上無(wú)法直接加載
類似Android中ImageView的scaleType屬性,flutter的Image控件也有其屬性Boxfit,而且這個(gè)屬性不僅僅適用于Image相關(guān)的Widget,F(xiàn)ittedBox也具有此屬性。
FittedBox會(huì)在自己的尺寸范圍內(nèi)縮放并且調(diào)整child位置,使得child適合其尺寸。
示例代碼:
new Container(
color: Colors.amberAccent,
width: 300.0,
height: 300.0,
child: new FittedBox(
fit: BoxFit.contain,
alignment: Alignment.topLeft,
child: new Container(
color: Colors.red,
child: new Text("FittedBox"),
),
),
)
看一下幾種縮放方式的區(qū)別:
7、Flutter構(gòu)建布局實(shí)例
Flutter布局機(jī)制的核心是Widget。在Flutter中,幾乎所有東西都是Widget - 甚至布局模型都是Widget。你在Flutter應(yīng)用中看到的圖像、圖標(biāo)和文本都是widget。 甚至你看不到的東西也是widget,例如行(row)、列(column)以及用來(lái)排列、約束和對(duì)齊這些可見(jiàn)widget的網(wǎng)格(grid)。
查看Flutter中文網(wǎng)的教程:在Flutter中構(gòu)建布局
常用Widget:
(1)Column和Row相對(duì)于Android中的LinearLayout,Column相對(duì)于Orientation.Vertical;Row相當(dāng)于Orientation.Horizontal。
(2)ListView ,GridView與Android中的同名控件效果等同
(3)Stack相當(dāng)于Android中的FrameLayout,但是它又具有RelativeLayout的一些屬性。
(4)Card相當(dāng)于Android中的CardView
(5)事件響應(yīng):Flutter并非為所有Widget都直接提供了點(diǎn)擊,長(zhǎng)按等事件響應(yīng),這時(shí)我們需要用 GestureDetector這個(gè)widget包裹需要響應(yīng)事件的widget來(lái)實(shí)現(xiàn)功能。
GestureDetector提供了如下手勢(shì):
??Tap
??onTapDown 指針已經(jīng)在特定位置與屏幕接觸
??onTapUp 指針停止在特定位置與屏幕接觸
??onTap tap事件觸發(fā)
??onTapCancel 先前指針觸發(fā)的onTapDown不會(huì)在觸發(fā)tap事件
??雙擊
??onDoubleTap 用戶快速連續(xù)兩次在同一位置輕敲屏幕.
??長(zhǎng)按
??onLongPress 指針在相同位置長(zhǎng)時(shí)間保持與屏幕接觸
??垂直拖動(dòng)
??onVerticalDragStart 指針已經(jīng)與屏幕接觸并可能開(kāi)始垂直移動(dòng)
??onVerticalDragUpdate 指針與屏幕接觸并已沿垂直方向移動(dòng).
??onVerticalDragEnd 先前與屏幕接觸并垂直移動(dòng)的指針不再與屏幕接觸,并且在停止接觸屏幕時(shí)以特定速度移動(dòng)
??水平拖動(dòng)
??onHorizontalDragStart 指針已經(jīng)接觸到屏幕并可能開(kāi)始水平移動(dòng)
??onHorizontalDragUpdate 指針與屏幕接觸并已沿水平方向移動(dòng)
??onHorizontalDragEnd 先前與屏幕接觸并水平移動(dòng)的指針不再與屏幕接觸,并在停止接觸屏幕時(shí)以特定速度移動(dòng)。
(6)Button:Flutter提供了幾種樣式的按鈕,分別為:
??FlatButton:扁平的,沒(méi)有陰影效果的。
??RaisedButton:有陰影效果的。
??FloatingActionButton:懸浮按鈕,類似Android上同名的控件。
??OutlineButton:線框按鈕,帶外邊框的按鈕。
(7)Expanded、Flexible:Expanded 這是個(gè)用來(lái)讓子項(xiàng)具有伸縮能力的widget,繼承自Flexible。它們兩個(gè)的默認(rèn)靈活系數(shù)是一樣的,但是fit參數(shù)不同,Expanded是默認(rèn)要占滿分配的空間的,而Flexible則默認(rèn)不需要。
(8)Ripple效果:Flutter中文網(wǎng)將InkWell翻譯成“墨水飛濺”效果,其實(shí)看到效果后,我們馬上就能聯(lián)想到Android中的ripple效果。
用法也是用InkWell套起想要達(dá)到效果的widget,具體屬性查看源碼注釋。
下面用一個(gè)具體的例子介紹布局和其他可能用到的Widget:
上圖是常見(jiàn)的聊天列表樣式,首先我們能想到的是整個(gè)界面是一個(gè)ListView,根據(jù)類型有左邊和右邊兩種樣式。由于flutter沒(méi)有xml布局,所有界面都是通過(guò)widget搭積木一樣,一層一層套起來(lái)的。
左側(cè)的顯示:最外層應(yīng)該是一個(gè)Row,Row中包含了一個(gè)CircleAvatar(沒(méi)錯(cuò),這個(gè)Widget官方直接提供了)和一個(gè)Text。
怎樣控制Text的背景樣式:
首先想到的就是外層套一個(gè)可以設(shè)置樣式的Container,通過(guò)給Container加一個(gè)decoration屬性,一般使用BoxDecoration,可以為Container設(shè)置背景顏色,前景顏色,邊框,圓角,圖片等能滿足大部分場(chǎng)景的樣式。
問(wèn)題出現(xiàn)了
Text本身是支持文字自動(dòng)換行的,Container本身如果沒(méi)有父控件限制也是包裹的,但因?yàn)橥饷娣帕艘粋€(gè)Row,就會(huì)出現(xiàn)溢出屏幕的問(wèn)題。經(jīng)過(guò)多番查找,我找到了一個(gè)Widget可以解決問(wèn)題——Flexible,在Container外面套一個(gè)Flexible就能解決問(wèn)題,此時(shí)需要注意的是,F(xiàn)lexible,Expanded等可以自適應(yīng)的繼承了Flex的控件,其父控件也必須是同類型。
接下來(lái)我們要控制文字的最長(zhǎng)顯示寬度,Container有一個(gè)屬性是constraints,它的類型是BoxConstraints,這個(gè)Widget可以設(shè)置最小最大寬高,不限制的話就用double.infinity(無(wú)限)。在經(jīng)過(guò)限制后,我們發(fā)現(xiàn)Flexible已經(jīng)不需要了,因?yàn)閷挾纫呀?jīng)限制住了=.=|||。
//獲取屏幕寬度的方法
double width = MediaQuery.of(context).size.width;
接下來(lái)我們按照Android中的理解,顯示右側(cè)頭像的消息,就在Row中先加入一個(gè)Text,再加入一個(gè)CircleAvatar。沒(méi)錯(cuò),但是怎樣居右顯示呢?經(jīng)過(guò)查詢資料發(fā)現(xiàn),Row通過(guò)textDirection屬性可以設(shè)置方向,我們將屬性設(shè)置成TextDirection.rtl,也就是rightToLeft,發(fā)現(xiàn)咦?怎么頭像跑到前面去了?那我們?cè)侔杨^像代碼移到前面,竟然對(duì)了。。也就說(shuō)明,Row的繪制流程都是根據(jù)children中最先加入的子widget來(lái)繪制的。
輸入框?qū)崿F(xiàn):
輸入框首先要保持在界面底部,怎么實(shí)現(xiàn)呢?了解到官方提供了一個(gè)BottomAppBar,將其設(shè)置給Scaffold中的bottomNavigationBar屬性。BottomAppBar的child給到一個(gè)Row控件,排列語(yǔ)音按鈕IconButton,輸入框TextField,更多按鈕IconButton。TextField外部要嵌套一個(gè)Container修飾樣式。運(yùn)行后發(fā)現(xiàn)整個(gè)界面都無(wú)法顯示,而注釋掉TextField就可以顯示,由此想到應(yīng)該是TextField的寬度不正常導(dǎo)致的,使用萬(wàn)能控件Flexible套在TextField的父級(jí)Container外后顯示正常。
接下來(lái)試試輸入文字,又出現(xiàn)坑了!BottomAppBar在輸入法彈出時(shí)無(wú)法自動(dòng)上移,確定了resizeToAvoidBottomPadding設(shè)置為true的情況依然無(wú)法解決問(wèn)題后,只好找其他方式。在stackoverflow上找到了另一種方案:將最下面的輸入布局連同ListView都放入Scaffold的body中,ListView外加上Expanded伸縮,最外層一個(gè)Container包裹,運(yùn)行完美,代碼如下:
@override
Widget build(BuildContext context) {
_getConversations();
return new Scaffold(
appBar: new AppBar(
title: new Text(mIsGroup
? mConversation.groupBean.groupName
: mConversation.contactBean.nickName != null
? mConversation.contactBean.nickName
: mConversation.contactBean.pin),
elevation: 0.5,
actions: <Widget>[
new IconButton(
icon: new Icon(
mIsGroup ? Icons.group : Icons.person,
size: 24,
color: Colors.black54,
),
onPressed: _goContactInfo),
],
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Expanded(
child: _buildConversations(),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.keyboard_voice), onPressed: null),
Flexible(
child: Container(
height: 40,
margin: EdgeInsets.fromLTRB(10, 6, 10, 6),
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.black12,
width: 0.5,
style: BorderStyle.solid,
),
borderRadius: BorderRadius.circular(4),
),
child: TextField(
decoration: InputDecoration(
hintText: '輸入內(nèi)容', border: InputBorder.none),
)),
),
Container(
margin: EdgeInsets.fromLTRB(0, 0, 10, 0),
child: IconButton(icon: Icon(Icons.add_circle_outline),onPressed: null,),
)
],
),
],
),
);
}
到此,就實(shí)現(xiàn)了圖中所示效果。
下面是item的布局代碼:
Widget _msgHolder(MessageBean message, BuildContext context) {
double width = MediaQuery.of(context).size.width;
double _maxWidth = width * 0.65;
return Row(
textDirection: message.from.pin == myInfo.pin?TextDirection.rtl:TextDirection.ltr,
children: <Widget>[
CircleAvatar(
backgroundImage: AssetImage(message.from.avatarUrl == null
? "assets/drawable/ava_group.png"
: message.from.avatarUrl),
),
GestureDetector(
onLongPress: () {
_showList(options);
},
child: Container(
constraints: BoxConstraints(
minWidth: 0,
maxWidth: _maxWidth,
minHeight: 0,
maxHeight: double.infinity),
margin: EdgeInsets.fromLTRB(10, 5, 5, 10),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.green,
border: Border.all(
color: Colors.green,
width: 0.5,
style: BorderStyle.solid,
),
borderRadius: BorderRadius.circular(4),
),
child: Text(
_getMessage(message),
style: TextStyle(color: Colors.white, fontSize: 16),
),
)),
],
);
}
Widget的顯示與隱藏
Flutter知識(shí)點(diǎn): Widget隱藏與顯示
8、Toast和Dialog
在聊天中,常見(jiàn)操作是長(zhǎng)按消息,彈出一個(gè)具有選項(xiàng)的Dialog,那么在Flutter中如何顯示常見(jiàn)的Toast和Dialog呢?
由于Flutter提供給安卓的大部分Widget都是基于Material設(shè)計(jì)的,所以Flutter并沒(méi)有提供Toast控件,而是提供了SnackBar。
//SnackBar的顯示
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("長(zhǎng)按消息"),
));
SnackBar不止能夠顯示Text,還可以任意加入widget。
此處有坑:
關(guān)于上段代碼中的context(BuildContext),你在任何方法里都可以取到context,但是運(yùn)行起來(lái)很可能會(huì)遇到context為null的情況,那么就需要傳入一個(gè)經(jīng)過(guò)了實(shí)例化的BuildContext。比如Scaffold中或者ListView.builder中的context,傳給SnackBar即可。
Dialog:
Flutter為Android提供了Dialog,AlertDialog,SimpleDialog三種常用對(duì)話框。想要實(shí)現(xiàn)我們的需求用SimpleDialog剛合適,效果如下:
showDialog<int>(
context: context,
builder: (BuildContext context) {
return new SimpleDialog(
children: options.map((value) {
return new SimpleDialogOption(
onPressed: () {
Navigator.pop(
context,
options.indexOf(
value)); //here passing the index to be return on item selection
},
child: new Text(
value,
style: TextStyle(
fontSize: 16,
),
), //item value
);
}).toList(),
);
})
9、數(shù)據(jù)存儲(chǔ)
Flutter知識(shí)點(diǎn):數(shù)據(jù)存儲(chǔ)之SharedPreferences
Flutter知識(shí)點(diǎn):數(shù)據(jù)存儲(chǔ)之File
Flutter知識(shí)點(diǎn):數(shù)據(jù)存儲(chǔ)之sqflite
官網(wǎng)sqflite頁(yè)面
下面的字段不能用于表的屬性名稱
"add","all","alter","and","as","autoincrement","between","case","check","collate","commit","constraint","create","default","deferrable","delete","distinct","drop","else","escape","except","exists","foreign","from","group","having","if","in","index","insert","intersect","into","is","isnull","join","limit","not","notnull","null","on","or","order","primary","references","select","set","table","then","to","transaction","union","unique","update","using","values","when","where"
10、Flutter常用插件
audio_recorder: any #錄音、播放
flutter_sound: ^1.1.5#錄音
dropdown_menu: ^1.1.0#下拉菜單
simple_permissions:#權(quán)限獲取
easy_alert:#彈框
amap_location: any #高德地圖
location: any #gogle位置獲取
barcode_scan 0.0.8#二維碼識(shí)別qr_mobile_vision: ^0.1.0 #二維碼識(shí)別 這個(gè)不好用
flutter_screenutil: ^0.3.0#屏幕適配工具類
flutter_spinkit: ^2.1.0#加載等待框
lpinyin: ^1.0.6#漢字轉(zhuǎn)拼音
shimmer: ^0.0.4#微光效果控件
qr_flutter: ^1.1.3#二維碼生成
url_launcher: any#啟動(dòng)URL的Flutter插件。支持網(wǎng)絡(luò),電話,短信和電子郵件
datetime_picker_formfield: ^0.1.3#時(shí)間選擇控件
flutter_picker: '^1.0.0'#選擇器
common_utils: '^1.0.1'#工具類 時(shí)間、日期、日志等
flutter_html: '^0.8.2'#靜態(tài)html標(biāo)記呈現(xiàn)為Flutter小部件
fluwx: '^0.3.0'#微信支付、分享、登錄
tobias: '^ 0.0.6#支付寶
cupertino_icons: '^0.1.2'#小圖標(biāo)控件
http: '^0.11.3+16'#網(wǎng)絡(luò)請(qǐng)求
html: '^0.13.3'#html解析
image_picker: '^0.4.5'#圖片選擇(相冊(cè)或拍照)
flutter_webview_plugin: any#webview展示
fluttertoast: any#toast提示框
shared_preferences: '^0.4.2'#shared_preferences存儲(chǔ)
transparent_image: '^0.1.0'#透明圖片控件
flutter_swiper : '^1.0.2'#輪播圖
charts_flutter: '^0.4.0'#統(tǒng)計(jì)圖表
path_provider: '^0.4.1'#獲取系統(tǒng)文件
cached_network_image: '0.4.1'#加載網(wǎng)絡(luò)圖片并本地緩存
sqflite: '^0.11.0+1'#sqllite數(shù)據(jù)庫(kù)操作
pull_to_refresh: '^1.1.5'#下拉刷新上拉加載更多
video_player: '0.6.1'#視頻播放
collection: '1.14.11'#集合操作工具類
device_info: '0.2.1'#獲取手機(jī)信息
flutter_svg: '^0.3.2'#展示svg圖標(biāo)控件
intl: any#國(guó)際化工具類
connectivity: '0.3.1'#鏈接網(wǎng)絡(luò)
flutter_staggered_grid_view:#瀑布流展示控件
flutter_file_manager:#文件管理
loader_search_bar:#導(dǎo)航欄搜索控件
flutter_image_compress : any#圖片壓縮
ota_update : any#App下載更新
flutter_slidable:#item側(cè)滑控件
——end