5分鐘學(xué)會(huì)Flutter開發(fā)
點(diǎn)擊“開發(fā)者技術(shù)前線”,選擇“星標(biāo)??”
讓一部分開發(fā)者看到未來

一、環(huán)境配置:
1.1 下載Flutter SDK
git clone https://github.com/flutter/flutter.git
1.2 配置環(huán)境變量
# FLUTTER_HOME為下載的Flutter文件夾路徑export FLUTTER_HOME=/Users/.../flutterexport PATH=$PATH:$FLUTTER_HOME/binexport PATH=$PATH:$FLUTTER_HOME/bin/cache/dart-sdk/bin
1.3 刷新環(huán)境變量
source ~/.bash_profilesource ~/.zshrc(如安裝zsh插件)
1.4 開發(fā)工具
1. Xcode + Android Studio(推薦) 2. Visual Studio Code

cd /Applications/Android\ Studio.app/Contents/jreln -s ../jre jdkln -s "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin" jdkflutter doctor
二、工程創(chuàng)建
2.1 創(chuàng)建Flutter項(xiàng)目
flutter create xxx
2.2 創(chuàng)建Flutter模塊(用于原生集成Flutter)
create --template module xxx
2.3 工程結(jié)構(gòu)
bd_flutter.dart_tool.............記錄依賴庫信息.idea..................當(dāng)前項(xiàng)目配置android................Android工程目錄iOS....................iOS工程目錄lib....................Flutter代碼目錄test...................單元測試目錄web....................Web工程目錄pubspec.yaml...........Pub第三方依賴配置文件,類似Cocoapods、Gradle
三、編程范式
3.1 命令式編程
3.2 聲明式編程
3.3 我們舉一個(gè)栗子,來幫我我們理解這兩者的區(qū)別



四、基礎(chǔ)架構(gòu)

4.1 Embedder
4.2 Engine
4.3 Framework
五、視圖渲染
5.1 Widget
5.2 渲染過程

//Text -> StatelessWidget -> Widgetclass Text extends StatelessWidget {}abstract class StatelessWidget extends Widget {StatelessElement createElement() => StatelessElement(this);}abstract class Widget extends DiagnosticableTree {Element createElement(); // 創(chuàng)建element抽象方法}
//Column -> Flex -> MultiChildRenderObjectWidget - > RenderObjectWidget -> Widgetclass Column extends Flex {}class Flex extends MultiChildRenderObjectWidget {// ?法實(shí)現(xiàn)RenderFlex createRenderObject(BuildContext context) {//返回RenderFlexreturn RenderFlex -> RenderBox -> RenderObject} }abstract class MultiChildRenderObjectWidget extends RenderObjectWidget {}abstract class RenderObjectWidget extends Widget {RenderObjectElement createElement();RenderObject createRenderObject(BuildContext context); // 抽象?法-創(chuàng)建RenderObjectvoid updateRenderObject(BuildContext context, covariant RenderObject renderObject) {}void didUnmountRenderObject(covariant RenderObject renderObject) { }}abstract class Widget extends DiagnosticableTree {Element createElement(); // 抽象?法-創(chuàng)建element}class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox,FlexParentData>,RenderBoxContainerDefaultsMixin<RenderBox,FlexParentData>,DebugOverflowIndicatorMixin {}abstract class RenderBox extends RenderObject {}
六、混合開發(fā)
6.1 Flutter調(diào)用原生方法
/*Flutter代碼*/static const platform = const MethodChannel("leo.com/getudid");void getUDID() async {final result = await platform.invokeMethod("nativeGetUDID"); // 要調(diào)?的?法// final result = await platform.invokeMethod("nativeGetUDID",["flutter參數(shù)"]);setState(() {_udid = result;});}
/*iOS代碼*/// 1.獲取FlutterViewControllerlet controller: FlutterViewController = window.rootViewController as!FlutterViewController;// 2.創(chuàng)建FlutterMethodChannel,跟controller?進(jìn)制消息通信let channel = FlutterMethodChannel(name: "leo.com/getudid", binaryMessenger:controller.binaryMessenger);// 3.監(jiān)聽channel調(diào)??法,當(dāng)flutter調(diào)?nativeGetUDID的時(shí)候調(diào)?channel.setMethodCallHandler { (call: FlutterMethodCall, result:FlutterResult) in// 1.判斷當(dāng)前是否是nativeGetUDIDguard call.method == "nativeGetUDID" else {result(FlutterMethodNotImplemented); // 報(bào)?個(gè)沒有?法的錯(cuò)誤return;}call.arguments; //傳遞過來的參數(shù)// 2.獲取UDIDlet udid = "xxxx-xxxx-xxxx-xxxx"result(udid) //回調(diào)值}
/*Android代碼*/private val CHANNEL = "leo.com/getudid"override fun configureFlutterEngine( flutterEngine: FlutterEngine) {GeneratedPluginRegistrant.registerWith(flutterEngine);// 1.創(chuàng)建MethodChannel對象val methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger,CHANNEL)// 2.添加調(diào)??法的回調(diào)methodChannel.setMethodCallHandler {// Note: this method is invoked on the main thread.call, result ->// 2.1.如果調(diào)?的?法是nativeGetUDID,那么正常執(zhí)?if (call.method == "nativeGetUDID") {// 2.1.1.調(diào)?另外?個(gè)?定義?法回去電量信息val udid = "xxxx-xxxx-xxxx-xxxx";result.success(udid)} else {//?法找不到,回調(diào)notImplementedresult.notImplemented()}}}
create --template module native_add_flutter
// CocoaPods集成flutter_application_path = '../native_add_flutter'load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb’)
// 初始化Flutter引擎 , 為引擎起名為leolet flutterEngine:FlutterEngine = FlutterEngine(name: "leo");// 啟動(dòng)flutter引擎,默認(rèn)函數(shù)??為mainflutterEngine.run();let flutterVC = FlutterViewController(engine: engine, nibName: nil, bundle: nil);flutterVC.modalPresentationStyle = .fullScreen;self.present(flutterVC, animated: true, completion: nil);
// 在gradle進(jìn)?配置// 創(chuàng)建Android項(xiàng)?、添加相關(guān)的依賴// 1、修改Android項(xiàng)?settings.gradlesetBinding(new Binding([gradle: this])) // newevaluate(new File( // newsettingsDir.parentFile, // new'native_add_flutter/.android/include_flutter.groovy' // new))include ':native_add_flutter'project(':native_add_flutter').projectDir = new File('../native_add_flutter')// 2、配置Android項(xiàng)?的build.gradledependencies {...implementation project(':flutter') //增加flutter依賴}// 3、AndroidManifest.xml配置<activity android:name="io.flutter.embedding.android.FlutterActivity"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize"/>
import io.flutter.embedding.android.FlutterActivity;public class MainActivity extends AppCompatActivity {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);startActivity(FlutterActivity.createDefaultIntent(this));}}
flutter create flutterdemo main.dart
// 導(dǎo)?類import 'package:flutter/material.dart';//??函數(shù),程序加載時(shí)調(diào)?void main() {runApp(MyApp()); //調(diào)?runApp?法,并初始化MyApp}class MyApp extends StatelessWidget {// This widget is the root of your application.Widget build(BuildContext context) { //初始化會(huì)調(diào)?build?法return MaterialApp( //Material為Google的?種UI?格,MaterialApp可為項(xiàng)?配置App標(biāo)題、主題等title: 'Flutter Demo',theme: ThemeData(// This is the theme of your application.//// Try running your application with "flutter run". You'll see the// application has a blue toolbar. Then, without quitting the app, try// changing the primarySwatch below to Colors.green and then invoke// "hot reload" (press "r" in the console where you ran "flutter run",// or simply save your changes to "hot reload" in a Flutter IDE).// Notice that the counter didn't reset back to zero; the application// is not restarted.primarySwatch: Colors.blue,),home: MyHomePage(title: 'Flutter Demo Home Page'), //設(shè)置主?為MyHomePage);}}//由于點(diǎn)擊需要更改Text顯示,所以此處繼承StatefulWidgetclass MyHomePage extends StatefulWidget {MyHomePage({Key? key, required this.title}) : super(key: key);// This widget is the home page of your application. It is stateful, meaning// that it has a State object (defined below) that contains fields that affect// how it looks.// This class is the configuration for the state. It holds the values (in this// case the title) provided by the parent (in this case the App widget) and// used by the build method of the State. Fields in a Widget subclass are// always marked "final".final String title;_MyHomePageState createState() => _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> {int _counter = 0;//下的按鈕的點(diǎn)擊事件void _incrementCounter() {// setState會(huì)標(biāo)記需要刷新UIsetState(() {// This call to setState tells the Flutter framework that something has// changed in this State, which causes it to rerun the build method below// so that the display can reflect the updated values. If we changed// _counter without calling setState(), then the build method would not be// called again, and so nothing would appear to happen._counter++; //點(diǎn)擊按鈕時(shí)候,counter+1, 并?動(dòng)更新UI顯示});}Widget build(BuildContext context) {// This method is rerun every time setState is called, for instance as done// by the _incrementCounter method above.//// The Flutter framework has been optimized to make rerunning build methods// fast, so that you can just rebuild anything that needs updating rather// than having to individually change instances of widgets.return Scaffold(appBar: AppBar( //配置導(dǎo)航// Here we take the value from the MyHomePage object that was created by// the App.build method, and use it to set our appbar title.title: Text(widget.title),),body: Center( //配置布局顯示在中?// Center is a layout widget. It takes a single child and positions it// in the middle of the parent.child: Column( //?種豎向布局?式,相當(dāng)于listview// Column is also a layout widget. It takes a list of children and// arranges them vertically. By default, it sizes itself to fit its// children horizontally, and tries to be as tall as its parent.//// Invoke "debug painting" (press "p" in the console, choose the// "Toggle Debug Paint" action from the Flutter Inspector in Android// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)// to see the wireframe for each widget.//// Column has various properties to control how it sizes itself and// how it positions its children. Here we use mainAxisAlignment to// center the children vertically; the main axis here is the vertical// axis because Columns are vertical (the cross axis would be// horizontal).mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ //返回多個(gè)widget數(shù)組,Text('You have pushed the button this many times:',),Text( '$_counter',//顯示_counter的值style: Theme.of(context).textTheme.headline4,//顯示樣式,使?主題的headline4顯示),],),),floatingActionButton: FloatingActionButton( //?個(gè)可點(diǎn)擊的按鈕,固定在右下?onPressed: _incrementCounter, //點(diǎn)擊事件tooltip: 'Increment',child: Icon(Icons.add), //按鈕顯示為內(nèi)部?帶的add圖?), // This trailing comma makes auto-formatting nicer for build methods.);}}
八、附:近期重要更新
支持java1.8
增加了JavaScript與Dart的通信通道
增加了對Android App Bundles的支持
通過減少調(diào)用構(gòu)造函數(shù)和靜態(tài)方法,提升AOT(預(yù)編譯)10%-20%的性能
添加了集成測試
提高熱重載性能
決定刪除動(dòng)態(tài)更新計(jì)劃
添加對Linux和Windows的Flutter運(yùn)行支持
優(yōu)化Flutter tools支持
支持32位和64位Android bundles
開始支持web端和實(shí)驗(yàn)性支持桌面端
桌面平臺(tái)實(shí)驗(yàn)性支持
新增24種語言環(huán)境支持
支持macOS Catalina和iOS 13
Android增加對構(gòu)建AAR的支持
支持Android 10
支持iOS13暗黑模式
可以將Flutter模塊集成到Android或iOS應(yīng)用中
將Web支持從開發(fā)版轉(zhuǎn)變?yōu)閎eta版;將MacOS支持納入開發(fā)版本
推出新工具DartPad(DartPad 是一個(gè)可以讓你在任何現(xiàn)代化的瀏覽器中體驗(yàn) Dart 編程語言線上工具)
減少18.5%應(yīng)用體積
提升了20%-37%導(dǎo)航性能
降低了40% iOS動(dòng)畫CPU/GPU使用率
增加對谷歌字體的支持:fonts.google.com
完成對Type Scale部分的重構(gòu),符合 2018 Material 設(shè)計(jì)規(guī)范
提升了iOS 50%渲染速度(iPhone5s+、iOS10+支持Metal 渲染);不完全支持扔使用OpenGL渲染
增強(qiáng)了UTF-8解碼
pubspec.yaml插件不再支持舊格式
在Visual Studio Code中預(yù)覽嵌入式Dart DevTools
引入新的混編插件-Pigeon,可以在Dart方法中直接調(diào)用Java/Objective-C/Kotlin/Swift方法并傳遞非原始數(shù)據(jù)對象。
增加應(yīng)用體積分析工具
提供了國際化和本地化工具,并實(shí)現(xiàn)了熱重載支持
支持Android 11;支持新的屏幕類型 (如挖孔屏和瀑布屏),以及同步Android 11動(dòng)畫效果
支持iOS 14、Xcode 12新圖標(biāo)以及對新iOS 14 App Clips功能的預(yù)覽支持;默認(rèn)模板版本從8.0升級(jí)到9.0
可正式使用的 Google Maps 和 WebView 插件,將 Android 和 iOS 系統(tǒng)的原生界面組件托管在 Flutter 應(yīng)用中
Web支持從測試版轉(zhuǎn)變?yōu)榉€(wěn)定版
除了HTML渲染,增加了CanvasKit渲染,桌面端瀏覽器會(huì)默認(rèn)調(diào)用CanvasKit版本,移動(dòng)端的瀏覽器會(huì)調(diào)用HTML版本。
混合開發(fā)多flutter實(shí)例(經(jīng)測試iOS平臺(tái)存在內(nèi)存問題)
桌面平臺(tái)的支持(beta)
Google Mobile Ads(Beta)
Dart 2.12 增加了空安全
更好的iOS、Android、Web跨平臺(tái)支持
Dart 2.13 更新,引入Type aliases
Flutter Web 提升穩(wěn)定性
優(yōu)化iOS端渲染動(dòng)畫幀時(shí)間、實(shí)現(xiàn)了增量iOS安裝,縮短更新安裝時(shí)間。
Android中引入延遲組件,允許Flutter應(yīng)用在運(yùn)行時(shí)下載包含提前編譯的代碼模塊,減少初始安裝大小。
— 完 —
點(diǎn)這里??關(guān)注我,記得標(biāo)星呀~
前線推出學(xué)習(xí)交流一定要備注:研究/工作方向+地點(diǎn)+學(xué)校/公司+昵稱(如JAVA+上海 掃碼加小編微信,進(jìn)群和大佬們零距離
END 后臺(tái)回復(fù)“電子書” “資料” 領(lǐng)取一份干貨,數(shù)百面試手冊等 歷史推薦
好文點(diǎn)個(gè)在看吧!
評論
圖片
表情
