Flutter-基礎認知

flutter 是什麼

flutter是Google基於Dart語言開發的移動應用開發框架,在保持原生性能的條件下實現了跨端編程。css

官方定義【 Flutter是一款移動應用程序SDK,一份代碼能夠同時生成iOS和Android兩個高性能、高保真的應用程序。】html

爲何學習flutter

體驗流暢且統一

因爲其統一在打包階段把flutter引擎打包入,統一使用引擎的Skia直接渲染,所以在排版、圖標、滾動、點擊等方面實現零差別。前端

遠大前景

google 新一代操做系統 Fuchsia 的 UI開發框架;vue

品質保證

google親自操刀Flutter以及Dart,可以不斷優化,Dart做爲新一代編程語言,可用於web、服務端、移動端、物聯網 開發,而且支持轉譯js,其煊赫一時程度可見一斑,並且做爲全新的語言,其編程體驗也是值得確定。html5

生態豐富

flutter 豐富的控件庫 以及 插件資源,極大得提升開發效率。node

技能準備

Dart

Dart於2013年年末發佈1.0版本,Google推出Dart 的目的是在 JavaScript 語言的基礎上,改進編程效率和軟件執行效率,並減小大型軟件的編程複雜性。它確實作到第一點, Dart 編寫的程序執行效率比 JavaScript 高出 42%到 130%, 其實這對於想投入Html5 而又憎惡 JavaScript的人來講是個福音。react

Flutter

基於Dart的跨平臺框架,這裏咱們所要學習的是Flutter相關Api, Flutter提供了至關豐富的Api,以往咱們在 Android/Ios中花大力氣寫的自定義控件,在Flutter中基本是信手拈來。android

Flutter官方網站-------Flutter中文網ios

Pub倉庫

Dart的包管理器,Pub之於Dart 就如 npm 之於 node.js, 須要注意的是dart插件分 FlutterWeb兩大類。 搜索插件庫css3

android/ios(可選)

開發者徹底能夠開發純Flutter應用。 若是須要Native支持的 Pub上也有大量的插件庫資源, 可是對於某些開發者的特殊需求(本身開發插件 or 開發混合App),就須要具有相應前端技能了。

環境工具搭建

環境

官方指導:安裝Flutter 整個過程簡單來講就是:

  1. git(Window用戶須要安裝 Git For Window) 克隆一份Flutter代碼到本地

  2. 配置環境變量(Flutter的Bin目錄)

另外:google還貼心得爲中國開發者提供了鏡像,你懂的。

有些人可能會疑惑,Flutter基於Dart 就如 Android基於Java , Ios 基於 OC, 爲何沒有安裝Dart的過程,其實這個過程已經在 1 步驟裏了, Flutter會自帶最新版本的Dart,目前是2.0, 可在在控制在查看Dart版本 (前提是你已經配置了Dart環境變量,官方教程沒有這一步).

工具選擇

若是你僅僅是想開發純Flutter應用,使用 VsCode 就足夠了,畢竟插件強大,內存佔用小。 安裝Dart插件

若是您須要自行開發插件 或者 開發混合 App, 那麼你須要 AndroidStudio 和 XCode。

測試環境

環境和工具安裝完成能夠測試Flutter安裝狀況,在terminal運行 flutter doctor

檢測安裝狀況

這也僅僅是用於參考,該命令工具備時候也不太準確,本身把握就好,其實什麼東西沒裝本身內心沒B+樹嗎?

工程目錄

建立工程

不管你是哪一種操做系統,哪一種開發工具,均可以使用

flutter create myapp

來生成Flutter工程, myapp 能夠是任何你想要的工程名。這是個人工程目錄:

工程目錄

  1. android

    裏面存放android相關, 和普通的Android項目目錄別無二致, 能夠進行混合開發,其實也是相似於React Native。

  2. ios

    同理普通的Ios項目目錄

  3. lib

    用於存放Dart文件用於Flutter執行, 其中 main.dart是程序入口,原生App殼,如Android 的Activity會加載FlutterView做爲ContentView, FlutterView就是Flutter加載main.dart渲染出的視圖,它有本身的堆棧管理。

  4. test 測試用文件夾

  5. pubspec.yaml

    Pub所用的配置文件,相似於npm的package.json, 用於Dart的包管理,使用的是 caret 語法,效果圖以下:

pubspec

pubspec.yaml 配置文件,當配置更新的時候,可使用 命令 **flutter packages get**拉取新的配置

name: 工程名

description: 文件描述

dependencies: Flutter工程依賴的庫,這裏的庫包含Pub倉庫、本地Pub插件文件夾、插件的git倉庫地址

flutter_test:: sdk: flutter: 這裏要引入flutter

cupertino_icons:: ^0.1.2 這裏引入ios風格的圖標

dev_dependencies: Flutter工程依賴的庫, 和 dependencies 不一樣在於,這個標籤下面定義的包只在開發模式生效,相似gradle 3.x 的 debugImplementation

  1. pubspec.lock

    pub自動生成的文件,和 pubspec.yaml 密切相關,用於指定程序包所依賴的每一個直接和傳遞依賴項的具體版本和其餘標識信息, pubspec.yaml 只列出直接依賴關係,鎖文件會確切得指定程序包所依賴的特定版本的包。

Flutter編寫

flutter的UI分層比較講究,從下到上依次爲 Dart:ui -> Render -> Animation -> Paint -> Widget -> MaterialWidget/cupertino 關於UI分層以及每一層的做用本篇不作討論。

若是你足夠無聊或者無可奈何,徹底能夠基於flutter的UI分層比較講究,從下到上依次爲 Dart:ui層或者Render作開發,不過涉及太過複雜的狀態管理渲染之類的工做。

本篇只作Flutter的基礎認識。

程序入口

首先咱們打開 lib 目錄下的 main.dart文件,咱們基於 widget層編寫(VsCode環境):

沒有根節點

程序的入口:

void main() => runApp(new MyApp());
複製代碼

該入口函數在整個app生命週期只會調用一次。 new MyApp() 會返回一個 Widget 控件用於渲染。 上圖代碼中返回了一個紅色的Contaner容器,效果以下:

效果圖

官方不推薦這麼作,不推薦直接把widget層的控件做爲根控件,緣由有我的認爲兩點(暫時想到兩點):

  • 有爲數很多的控件不支持直接放置(好比:Text 、 Icon),必需要 MaterialApp或者WidgetApp做爲父節點。
  • 直接放置須要開發者做大量的工做來調整佈局、樣式 等。

推薦使用 MaterialApp 做爲程序根節點,緣由以下:

  • 統一規範,MaterialApp 引入了 Material Design,仍是至關漂亮的,開發者幾乎不須要作額外的佈局、樣式 編碼就能達到產品級視覺效果, 固然能夠根據需求進行微調。
  • MaterialApp 提供了大量的美觀、功能豐富的控件,放棄MaterialApp等於放棄了一整片森林。

正確的姿式是這樣的:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Center(child: Text('我是標題')),
          actions: <Widget>[
            Icon(Icons.flight_takeoff),
          ],
        ),
        drawer: Text(''),
        body: new ListView.builder(
          itemCount: 12,
          itemBuilder: (BuildContext context, int index){
              return ListTile(title: Center(child: Text("我是第${index}個item")),);
          },
        )
      ),
複製代碼

MaterialApp 做爲根節點, Scafford 腳手架控件,提供了 Drawer、ToolBar、Body 等等,咱們能夠看看這 27 行代碼能實現什麼效果。

materaial_style

就醬紫,好好想像Android/Ios 實現這效果須要多少文件 多少 代碼吧。

控件類型

咱們Flutter編碼通常都是在 Widget這一層, 上面談到 程序的 入口是

void main() => runApp(new MyApp());
複製代碼

他的做用是建立整個widget視圖,整個生命週期只調用一次,那咱們怎麼怎麼更新頁面數據呢,咱們是否是得保存 Widget 的引用從新設置相應的屬性呢?

答案是

No!

咱們看一下Widget的具體實現:

@immutable
abstract class Widget extends DiagnosticableTree {
複製代碼

被加上了 @immutable 註解,這意味着控件不可被修改,只能被從新建立。 而咱們平時編寫 Flutter 繼承的是:

abstract class StatelessWidget extends Widget {
					&
abstract class StatefulWidget extends Widget {

複製代碼

所以,咱們不能對已建立的Widget進行修改,那麼咱們有兩個問題:

  1. 咱們應該如何 更新頁面數據以及佈局 ?
  2. StatelessWidgetStatefulWidget 什麼玩意兒,什麼區別 ?

咱們嘗試着同時看這兩個問題,StatefulWidget 擁有 StatelessWidget 的全部功能,也就是說 StatelessWidget 是他的子集。 StatefulWidget 多了什麼?

/**
 * StatefulWidget
 */
class TestStateFulWidget extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
      return TestStateFulState();
  }
}

/**
 * state
 */
class TestStateFulState extends State<TestStateFulWidget>{
  int _index = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Padding(padding: const EdgeInsets.only(top: 200.0),),
        Text('Count To $_index', style: TextStyle(fontSize: 50.0, color: Colors.red),),
        Padding(padding: const EdgeInsets.only(top: 60.0),),
        FloatingActionButton(   //這是浮動的按鈕,支持點擊從而觸發 onPressed()
          child: Text('Click'),
          onPressed: () {      //onPressed()方法裏面對_index自增,而且調用setState(() {})               
            _index++;
            setState(() {});
          },
        ),
      ],
    );
  }
}

複製代碼

效果圖

device_count

具體效果是點擊 Click 浮動按鈕, 上方的數字增長 1 ,這就是數據更新。

每一個StateFulWidget 維護一個 State 對象,當咱們對 相關數據更新後 而且 調用了** setState(() {})** 方法,這樣就吧 該 Widget 標記爲 dirty ,所以會觸發控件的更新、替換、刪除 等。

打包 ( 以Android爲例 )

debug

Flutter開發過程編譯會產生 debugapk 包,查看一下咱們打出的 debug 包: 在 gsy/build/app/outputs/apk/debug/app-debug.apk 目錄 利用 Android Studio 分析

debug_apk

竟然有 31M 我可什麼都沒有放啊,大頭都在 lib, 這什麼鬼, libflutter.so是什麼

這是Flutter虛擬機器, 官方的定義是:

The Flutter Engine is a portable runtime for hosting Flutter applications.

其實這也是Flutter能夠跨平臺統一的根本所在。

若是你開發Flutter 你會逐漸意識到,爲何感受 安裝包 卡卡的, 真的有官方宣稱的 60 幀嗎,或者平均50幀。 debug包所運行的東西太多啦, 主要是爲了方便開發者開發, 因此這點不用擔憂,咱們嘗試着打包release 包。

release

終端運行:

flutter build apk

複製代碼

一樣查看release包:

只有不足 9M 了,而且體驗發現,release包幀率至關得高,甚至比 native開發一樣的頁面幀率都要高(僅僅針對示本例而言).

主流跨平臺框架

維度 Hybird Weex RN Flutter
開發語言 html5+css3+js vue+js+css3 react+js+css3 Dart
是否摒棄標籤語言
動畫效果支持 通常
用戶體驗性 通常 流暢 流暢 流暢
插件豐富程度 豐富 較豐富 較豐富 較豐富
界面開發難易程度 較高 較低 較低
是否支持熱更新
是否支持和現有項目集
最低支持Android版本 webview支持狀況 4.1+ 4.2+
最低支持IOS版本 webview支持狀況 iOS8.0+ iOS8+

以上部分數據僅僅是我的以及部分開發同窗觀點,勿噴。

總結

整體來講Flutter是一門值得學習的技術,有理由相信 google 的Flutter團隊會和Dart團隊保持密切的合做,而且Dart 虛擬機會更加高效,更加適合Flutter,這是其餘框架所不具有的優點

並且Fuchsia系統也採用Flutter做爲界面框架,因此,你懂的,就不說了。

相關文章
相關標籤/搜索