開源一個(gè)Flutter版WanAndroid客戶端

1. 前言

項(xiàng)目地址: https://github.com/xfhy/WanAndroid-Flutter

前段時(shí)間抽了點(diǎn)業(yè)余時(shí)間學(xué)了點(diǎn)Flutter入門,打算寫個(gè)簡(jiǎn)單項(xiàng)目練練手.說(shuō)實(shí)話,只有真正動(dòng)手寫東西才能真正切身感受到Flutter的魅力,剛開始學(xué)的時(shí)候?qū)懖季痔貏e難受,各種嵌套,很煩. 后面多寫一點(diǎn)兒之后感覺也還是勉強(qiáng)可以接受,各種Widget操作起來(lái)也還是容易.

Flutter目前我認(rèn)為是最合理的跨平臺(tái)方案,只需要native提供畫布,Flutter直接自己在上面畫Widget,就單憑這一點(diǎn)就和RN截然不同.RN還需要JS和Java進(jìn)行中轉(zhuǎn),多了一層,肯定會(huì)慢很多,而且還不能自己畫.

再來(lái)說(shuō)說(shuō)開發(fā)和發(fā)布,支持JIT和AOT.平時(shí)開發(fā)使用JIT,可以快速熱加載,及時(shí)將代碼變動(dòng)傳遞給flutter app,這其實(shí)可以大大提升開發(fā)效率.及時(shí)查看UI和邏輯是否正確,不像原生開發(fā)還需要重新編譯,花費(fèi)很多時(shí)間.然后Flutter在發(fā)布(release包)的時(shí)候,采用AOT,運(yùn)行時(shí)直接指向Native(arm)代碼,高效.

可能有時(shí)候Flutter需要和native通信,比如使用相機(jī)之類的,這時(shí)會(huì)使用到channel技術(shù),但是這個(gè)是C++層次的,性能好.

所以,了解一下Flutter.

2. 下載試玩

掃描二維碼下載


image

3. 技術(shù)點(diǎn)

  • 封裝 上拉加載,下拉刷新
  • dio進(jìn)行網(wǎng)絡(luò)請(qǐng)求,統(tǒng)一封裝get,post
  • 封裝banner
  • Future
  • 路由,跳轉(zhuǎn)界面
  • 事件總線 event_bus
  • toast
  • SharedPreference
  • ....

4. 項(xiàng)目截圖

5. 遇到的問題

5.1 引入第三方庫(kù)

  1. 首先去官網(wǎng)package搜索.
  2. 找到相應(yīng)插件,點(diǎn)進(jìn)詳情,切換到Installing tab,然后在pubspec.yaml中引入該插件.
  3. 在本項(xiàng)目控制臺(tái),輸入flutter pub get. 即引入三方庫(kù)完成.

5.2 loading

當(dāng)頁(yè)面正在loading時(shí),需要一個(gè)Widget來(lái)占位,不然Widget為空要報(bào)錯(cuò).

5.3 運(yùn)行在iOS上

  1. 首先得安裝Xcode(7.8G)
  2. 然后安裝 cocoapods sudo gem install cocoapods
  3. 然后在ios工程下,執(zhí)行pod install,引入那些依賴
  4. 然后用AS打開ios項(xiàng)目里面的Info.plist,點(diǎn)擊右上角的用Xcode打開.
  5. 編輯Podfile,將頂部的platform :ios, '9.0' 注釋放開
  6. 運(yùn)行到模擬器上.

5.4 如何快速解析json

Flutter不支持運(yùn)行時(shí)反射,所以沒有像Gson這樣自動(dòng)解析JSON的庫(kù)來(lái)降低解析成本.在Flutter中解析JSON需要完全手動(dòng)進(jìn)行操作,麻煩.

可以在AS上裝FlutterJsonBeanFactory這個(gè)插件,然后右鍵New->JsonToDartBeanAction,輸入文件名和json數(shù)據(jù).即可自動(dòng)生成bean對(duì)象,和它所對(duì)應(yīng)的解析代碼.

原理是它生成了一個(gè)JsonConvert,然后這里面可以根據(jù)運(yùn)行時(shí)type去選擇應(yīng)該解析哪一個(gè)類對(duì)象.
然后bean類在聲明的時(shí)候是混入了JsonConvert的,可以直接使用JsonConvert里面的方法,完美.

5.5 Flutter ScrollView (滾動(dòng)視圖)

ScrollView是一個(gè)帶有滾動(dòng)的視圖組件,它本身由三部分組成

  • Scrollable - 它監(jiān)聽各種用戶手勢(shì)并實(shí)現(xiàn)滾動(dòng)的交互設(shè)計(jì)陕习。
  • Viewport - 它通過在滾動(dòng)視圖內(nèi)僅顯示一部分小部件來(lái)實(shí)現(xiàn)滾動(dòng)的可視化設(shè)計(jì)创千。
  • Slider - 它們是可以組合以創(chuàng)建各種滾動(dòng)效果的小部件潮峦,如列表,網(wǎng)格和擴(kuò)展標(biāo)題荆姆。

Scroll是一個(gè)抽象類,通常使用CustomScrollView

CustomScrollView(
    shrinkWrap: true,
    // 內(nèi)容
    slivers: <Widget>[
        new SliverPadding(
            padding: const EdgeInsets.all(20.0),
            sliver: new SliverList(
                delegate: new SliverChildListDelegate(
                    <Widget>[
                        const Text('A'),
                        const Text('B'),
                        const Text('C'),
                        const Text('D'),
                    ],
                ),
            ),
        ),
    ],
)

5.6 處理Text超出問題

可以放Row或Column中,用Expanded包起來(lái),然后用maxLines控制行數(shù),用overflow: TextOverflow.ellipsis,控制超出部分的展示.

5.7 讓一個(gè)ListView支持下拉刷新

非常簡(jiǎn)單,
使用官方自帶的RefreshIndicator即可,將listview放child,然后實(shí)現(xiàn)一個(gè)_pullToRefresh下拉刷新時(shí)調(diào)用的方法(做下拉刷新的邏輯).

RefreshIndicator(
      child: listView,
      onRefresh: _pullToRefresh,
    );

Future<void> _pullToRefresh() {
    loadData();
    //這里Feature不能返回 null
    return Future(() => LogUtil.d("lalala"));
  }

5.8 獲取屏幕寬度,高度

MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height

5.9 封裝通用標(biāo)題欄

標(biāo)題欄,每個(gè)界面都需要,所以封裝一個(gè),取需.

///get通用狀態(tài)欄
static AppBar getCommonAppBar(BuildContext context, String title, {double fontSize, List<Widget> actions}) {
if (title == null) {
  title = "";
}
return AppBar(
  leading: IconButton(
    icon: Icon(
      Icons.arrow_back,
      color: Colors.white,
    ),
    //點(diǎn)擊返回
    onPressed: () {
      if (context != null) {
        Navigator.pop(context);
      }
    },
  ),
  title: Text(
    title,
    style: TextStyle(
      color: Colors.white,
      fontSize: fontSize == null ? 18.0 : fontSize,
    ),
  ),
  //標(biāo)題欄居中
  centerTitle: true,
  //右邊的action 按鈕
  actions: actions == null ? <Widget>[] : actions,
);
}

5.10 格式化String

dart中格式化String,需要引入三方庫(kù)sprintf,使用方式如下:

sprintf("lg/collect/%s/json", [15615]);

5.11 獲取Android/iOS本地目錄

需要引入三方庫(kù)path_provider,用于查找文件系統(tǒng)上的常用位置,支持Android和iOS.免得去寫一原生代碼,這個(gè)三方庫(kù)幫我們封裝好了.

Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;

Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;

5.12 展示一個(gè)Dialog

以下方法是dart的material包下面的方法.

//展示對(duì)話框
showDialog(
        context: context,
        barrierDismissible: false,
        builder: (_) {
          return SpinKitFadingCircle(
            color: AppColors.colorPrimary,
          );
        });

//取消對(duì)話框
Navigator.of(context).pop();

5.13 間距的簡(jiǎn)單方式

可以用Padding和margin來(lái)實(shí)現(xiàn).其實(shí)還有一種方式,可以在Column和Row中快速增加一段間距,利用SizedBox,類似Android中的Space

SizedBox(width: 10.0),

5.14 收起軟鍵盤

有時(shí)候需要在點(diǎn)擊某些按鈕時(shí)收起軟鍵盤

FocusScope.of(context).requestFocus(FocusNode());

5.15 讓ListView的item點(diǎn)擊時(shí)有水波紋效果

用InkWell把Item包起來(lái)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市映凳,隨后出現(xiàn)的幾起案子胆筒,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仆救,死亡現(xiàn)場(chǎng)離奇詭異抒和,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)彤蔽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門摧莽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人顿痪,你說(shuō)我怎么就攤上這事镊辕。” “怎么了蚁袭?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵丑蛤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我撕阎,道長(zhǎng)受裹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任虏束,我火速辦了婚禮棉饶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘镇匀。我一直安慰自己照藻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布汗侵。 她就那樣靜靜地躺著幸缕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晰韵。 梳的紋絲不亂的頭發(fā)上发乔,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天,我揣著相機(jī)與錄音雪猪,去河邊找鬼栏尚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛只恨,可吹牛的內(nèi)容都是我干的译仗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼官觅,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纵菌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起休涤,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤咱圆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闷堡,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隘膘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杠览。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弯菊。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖踱阿,靈堂內(nèi)的尸體忽然破棺而出管钳,到底是詐尸還是另有隱情,我是刑警寧澤软舌,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布才漆,位于F島的核電站,受9級(jí)特大地震影響佛点,放射性物質(zhì)發(fā)生泄漏醇滥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一超营、第九天 我趴在偏房一處隱蔽的房頂上張望鸳玩。 院中可真熱鬧,春花似錦演闭、人聲如沸不跟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)窝革。三九已至,卻和暖如春吕座,著一層夾襖步出監(jiān)牢的瞬間虐译,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工米诉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菱蔬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓史侣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親魏身。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惊橱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 胡常洲50多歲煉廠人
    李曼瑛一家庭教育閱讀 110評(píng)論 0 0
  • 發(fā)現(xiàn)現(xiàn)在自己讀的書真的太少了,所以很多時(shí)候開頭都想用時(shí)間過得真快箭昵,時(shí)間飛逝這么兩句税朴。 但是白駒過隙,彈指一揮間卻很...
    march_elle閱讀 180評(píng)論 0 0
  • 三月有你 四月有你 五月你走了 六月是他自己 七月八月是雨季 九月十月連泡沫里帶著香氣 冬月煮酒臘月燒起了肉 一月...
    Fanderix閱讀 186評(píng)論 0 0
  • 月近中秋好時(shí)節(jié), 人將古稀心意愜正林。 喜看新種麥苗綠泡一, 哪管衰草與黃葉。 秦時(shí)明月今秋夜觅廓, 仰首向天思明月鼻忠。 明月閱...
    滄海桑田_7c8e閱讀 157評(píng)論 0 0
  • 感覺時(shí)間又過了很長(zhǎng)時(shí)間了啊 今天陰歷六月六 挺好 今天來(lái)細(xì)數(shù)一下陪我每個(gè)年齡段的小說(shuō) 啟蒙階段 灌籃高手 龍珠 名...
    阿卡貝拉的調(diào)調(diào)閱讀 203評(píng)論 0 1