Flutter 從發佈之日起我就對其心心念唸了很久。 奈何這段時間實在是太忙了,加之本身拖延症時不時發做下,一直都抽不出時間來學習這個跨平臺框架。html
一轉眼 Flutter 1.2 都已經發布了,這下實在是坐不住了。特意花了一週的時間來作了 一文 這個 APP 。以此來簡單瞭解下這款全新跨平臺框架的魅力。android
回到標題,既然是編寫第二個 Flutter APP,那就要求各位觀衆老爺本身對照着官方的 First Flutter APP 擼一遍。(中文連接:flutterchina.club/get-started…)git
萬事開頭難,這部分包含了 dart 語言特性的學習,和 Flutter 框架一些特性的體驗。github
若是你也是像我同樣只是花兩個小時簡單看了下 dart 語言的新特性就直接來擼第一個 APP。寫的時候可能會感受老是在雲裏霧裏,不少地方都不明白。數據庫
別擔憂,這是正常現象,對咱們這種只想初步體驗的用戶來講,沒有系統的學習,這種狀況纔是正常現象。segmentfault
保持開放的心態,多學多看。碰到不懂的,多查,碰到不知道怎麼寫的,多看官方的源碼實現,等代碼量上去了,天然就熟練了。緩存
照着官方示例完成了本身了的第一個 APP 編寫,是否是頗有成就感?激動之餘,彷佛感受少了點什麼。框架
沒錯,畢竟只是照着官方的示例敲了一遍,說是 APP 也略簡陋了。是否是火燒眉毛的想作點什麼來鞏固下本身的學習呢。async
此次就跟着我一塊兒從項目的立項開始你的第二個 APP 吧。ide
因爲項目一週的時間限制,本次就要求項目儘量的簡單,頁面儘量的少。且,要儘量的完成多的功能點,因而 一文 就誕生了。
一文 是基於每日一文 API 開發的一款全新的 Flutter APP。
注意:在源代碼中,一個頁面可能包含多個功能實現,在實際作的時候,請依據 APP 預覽一項一項進行實現。
源代碼並非標準答案,有問題歡迎提交 PR 進行貢獻。
API 來源:github.com/jokermonn/-…
分析 API 進行聯網實現,主要要求實現聯網獲取文章,獲取後進行 Json 解析到 bean,而後進行簡單的錯誤 handle。
參考文章:
按照原生 APP 開發的套路,用於初始化以及展現廣告的 Splash 是必不可少的。
第一個頁面,主要要求掌握頁面編寫的常規套路以及 StatefulWidget 的生命週期等。
好比 class SplashPage
的寫法:
class SplashPage extends StatefulWidget {
SplashPage({Key key, this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() {
return _SplashPageState();
}
}
複製代碼
而後就是 class _SplashPageState
的編寫。
佈局就是一張圖片:
import 'package:flutter/material.dart';
class SplashPage extends StatefulWidget {
SplashPage({Key key, this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() {
return _SplashPageState();
}
}
class _SplashPageState extends State<SplashPage> {
@override
void initState() {
// TODO: do something to init
super.initState();
}
@override
Widget build(BuildContext context) {
return Builder(builder: (context) {
return Container(
child: Image(image: AssetImage('assets/images/splash.png'), fit: BoxFit.fill,),
);
});
}
}
複製代碼
生命週期以下:
圖片轉載自segmentfault.com/a/119000001…
具體 Splash 頁面講解參考個人博客:Flutter 開發 Android & IOS 啓動頁 splash page
主頁面主要是對文章進行展現以及相關設置項。
點擊左上角能夠彈出相關配置彈窗。
考慮到佈局的複雜度,這裏能夠將底部彈窗抽離出單獨寫進一個 .dart
文件。
從這部分就涉及到各個控件的使用和狀態設置,點擊事件等內容。
這部分基本就是程序的核心內容了。
完成了該部分以後就是對程序進行優化,添加數據庫來緩存數據,日期判斷切換,文章收藏等。
這個部分是耗時最長的,也是從磕磕碰碰到逐漸熟練的過程。
最後就是國際化,添加資源和打包等一些雜項了,具體參見
從剛開始看 dart 語法,到這個項目開發完成。斷斷續續一共持續了三週的時間。天天抽出一到兩個小時,合計一共是 56 小時左右。減去畫 APP 圖標,啓動頁面圖片的兩個小時,勉強算得上八小時工做制的一週。
這一週的使用過程當中,Flutter 有些特性讓人感受相見恨晚:語法特性(類型動態檢查,支持 .?
??
操做符)、簡單方便完備的 UI 方案、Hot Reload等。可是諸如複雜冗長的 view tree、資源的硬編碼、糟糕的 UI 控件 API 等又讓人頭痛不已。
在初步使用 Flutter 以後,我發覺彷佛 Flutter 短期內並不能讓我不學習原生開發就直接使用 Flutter 解決移動客戶端開發。
在不斷的使(zhe)用(teng)過程當中,發現碰到好多問題仍是須要你必須用原生開發的知識去解決相應的問題。 好比項目裏面獲取已收藏文章,是這樣從數據庫裏面獲取文件的:
Future<List<ArticleBean>> getStarred() async {
List<ArticleBean> articles = List();
Database db = await getDB();
List<Map<String, dynamic>> maps =
await db.query(name, columns: [columnId, columnStarred, columnDate, columnData], where: "$columnStarred = ?", whereArgs: [true]);
if (maps.length > 0) {
for (Map<String, dynamic> map in maps) {
ArticleBean article = ArticleBean.fromJson(map);
articles.add(article);
}
}
return articles;
}
複製代碼
請看核心查詢代碼
await db.query(name, columns: [columnId, columnStarred, columnDate, columnData], where: "$columnStarred = ?", whereArgs: [true]);
複製代碼
這裏就是獲取全部 starred 爲 true 的列。
可是實際運行的時候,發如今 Android 設備上面老是獲取不到。
Android 數據庫使用的是 Sqlite,不能存儲 bool(boolean)。相反,布爾值被存儲爲整數 0(false)和 1(true)。
故上述代碼要改爲下面的代碼才生效。
await db.query(name, columns: [columnId, columnStarred, columnDate, columnData], where: "$columnStarred > ?", whereArgs: [0]);
複製代碼
這只是一個很小的簡單例子,可是也說明了在 Flutter 上面並不能老是幫你解決原生的一些坑(這其實取決於各個框架的開發者爲你作了多少兼容處理)。
本文到這裏就要結束了,不怎麼涉及具體代碼,只是一週時間的 Flutter 簡單上手。若是你們對項目有興趣,歡迎你們 star、fork 以及提交 PR,謝謝你們。