一個高顏值Flutter版WanAndroid客戶端

1. 前言

項目地址: https://github.com/xfhy/WanAndroid-Flutterios

前段時間抽了點業餘時間學了點Flutter入門,打算寫個簡單項目練練手.說實話,只有真正動手寫東西才能真正切身感覺到Flutter的魅力,剛開始學的時候寫佈局特別難受,各類嵌套,很煩. 後面多寫一點兒以後感受也仍是勉強能夠接受,各類Widget操做起來也仍是容易.git

Flutter目前我認爲是最合理的跨平臺方案,只須要native提供畫布,Flutter直接本身在上面畫Widget,就單憑這一點就和RN大相徑庭.RN還須要JS和Java進行中轉,多了一層,確定會慢不少,並且還不能本身畫.github

再來講說開發和發佈,支持JIT和AOT.平時開發使用JIT,能夠快速熱加載,及時將代碼變更傳遞給flutter app,這其實能夠大大提高開發效率.及時查看UI和邏輯是否正確,不像原生開發還須要從新編譯,花費不少時間.而後Flutter在發佈(release包)的時候,採用AOT,運行時直接指向Native(arm)代碼,高效.json

可能有時候Flutter須要和native通訊,好比使用相機之類的,這時會使用到channel技術,可是這個是C++層次的,性能好.markdown

因此,瞭解一下Flutter.網絡

2. 下載試玩

掃描二維碼下載 app

3. 技術點

  • 封裝 上拉加載,下拉刷新
  • dio進行網絡請求,統一封裝get,post
  • 封裝banner
  • Future
  • 路由,跳轉界面
  • 事件總線 event_bus
  • toast
  • SharedPreference
  • ....

4. 項目截圖

image1 image2 image3 image4 image6 image6

5. 遇到的問題

5.1 引入第三方庫

  1. 首先去官網package搜索.
  2. 找到相應插件,點進詳情,切換到Installing tab,而後在pubspec.yaml中引入該插件.
  3. 在本項目控制檯,輸入flutter pub get. 即引入三方庫完成.

5.2 loading

當頁面正在loading時,須要一個Widget來佔位,否則Widget爲空要報錯.ide

5.3 運行在iOS上

  1. 首先得安裝Xcode(7.8G)
  2. 而後安裝 cocoapods sudo gem install cocoapods
  3. 而後在ios工程下,執行pod install,引入那些依賴
  4. 而後用AS打開ios項目裏面的Info.plist,點擊右上角的用Xcode打開.
  5. 編輯Podfile,將頂部的platform :ios, '9.0' 註釋放開
  6. 運行到模擬器上.

5.4 如何快速解析json

Flutter不支持運行時反射,因此沒有像Gson這樣自動解析JSON的庫來下降解析成本.在Flutter中解析JSON須要徹底手動進行操做,麻煩.oop

能夠在AS上裝FlutterJsonBeanFactory這個插件,而後右鍵New->JsonToDartBeanAction,輸入文件名和json數據.便可自動生成bean對象,和它所對應的解析代碼.佈局

原理是它生成了一個JsonConvert,而後這裏面能夠根據運行時type去選擇應該解析哪個類對象. 而後bean類在聲明的時候是混入了JsonConvert的,能夠直接使用JsonConvert裏面的方法,完美.

5.5 Flutter ScrollView (滾動視圖)

ScrollView是一個帶有滾動的視圖組件,它自己由三部分組成

  • Scrollable - 它監聽各類用戶手勢並實現滾動的交互設計。
  • Viewport - 它經過在滾動視圖內僅顯示一部分小部件來實現滾動的可視化設計。
  • Slider - 它們是能夠組合以建立各類滾動效果的小部件,如列表,網格和擴展標題。

Scroll是一個抽象類,一般使用CustomScrollView

CustomScrollView(
    shrinkWrap: true,
    // 內容
    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包起來,而後用maxLines控制行數,用overflow: TextOverflow.ellipsis,控制超出部分的展現.

5.7 讓一個ListView支持下拉刷新

很是簡單, 使用官方自帶的RefreshIndicator便可,將listview放child,而後實現一個_pullToRefresh下拉刷新時調用的方法(作下拉刷新的邏輯).

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 封裝通用標題欄

標題欄,每一個界面都須要,因此封裝一個,取需.

///get通用狀態欄
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,
    ),
    //點擊返回
    onPressed: () {
      if (context != null) {
        Navigator.pop(context);
      }
    },
  ),
  title: Text(
    title,
    style: TextStyle(
      color: Colors.white,
      fontSize: fontSize == null ? 18.0 : fontSize,
    ),
  ),
  //標題欄居中
  centerTitle: true,
  //右邊的action 按鈕
  actions: actions == null ? <Widget>[] : actions,
);
}
複製代碼

5.10 格式化String

dart中格式化String,須要引入三方庫sprintf,使用方式以下:

sprintf("lg/collect/%s/json", [15615]);
複製代碼

5.11 獲取Android/iOS本地目錄

須要引入三方庫path_provider,用於查找文件系統上的經常使用位置,支持Android和iOS.省得去寫一原生代碼,這個三方庫幫咱們封裝好了.

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

Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
複製代碼

5.12 展現一個Dialog

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

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

//取消對話框
Navigator.of(context).pop();
複製代碼

5.13 間距的簡單方式

能夠用Padding和margin來實現.其實還有一種方式,能夠在Column和Row中快速增長一段間距,利用SizedBox,相似Android中的Space

SizedBox(width: 10.0),
複製代碼

5.14 收起軟鍵盤

有時候須要在點擊某些按鈕時收起軟鍵盤

FocusScope.of(context).requestFocus(FocusNode());
複製代碼

5.15 讓ListView的item點擊時有水波紋效果

用InkWell把Item包起來

相關文章
相關標籤/搜索