flutter開發系列(搭建基礎的flutter環境)

小jerry發表於2021-03-24

關於APP開發,一直以來有非常多的方案。不管是安卓和iOS的原生開發、還是所謂的套殼開發,還有近幾年比較火的react-native以及uni-app。從開發效率和使用者體驗上綜合考慮,都各有利弊。19年開始flutter作為一種解決方案漸漸地進入大家的視野,2020年flutter的star量成倍的上漲,說明這個方案正在越來越被大家所接受。

image.png 對這個新生事物非常的有興趣,最近也是剛好借了一個契機,花了不到兩週的時間,學語法、搭環境,使用flutter + H5的方式實現了一個比較基礎的APP架構,最後完美執行在安卓和iOS的真機上:

image.png

什麼是flutter?

官方定義:

Flutter 是 Google 開源的 UI 工具包,幫助開發者通過一套程式碼庫高效構建多平臺精美應用,支援移動、Web、桌面和嵌入式平臺。

安裝與配置

一、安裝

要完整的跑起來一個flutter專案,大概需要下面這些工具:

1、Android Studio + avd

2、flutter SDK(包含Dart SDK不用單獨下載)

3、vscode、webstorm、IDEA(這個看個人喜好)

4、java JDK(官網下載得註冊)

5、Android SDK(這個直接在Android Studio裡面安裝)

6、需要各種模擬器(推薦pixel 和Xcode,一個安卓一個iOS)

關於java JDK和Android Studio 安裝包,如果需要的話可以私信

1、下載flutter SDK

去flutter官網下載其最新可用的安裝包,我選擇的是2.0.1beta穩定版(flutter.dev/docs/develo…)

2、解壓安裝包

將安裝包zip解壓到你想安裝Flutter SDK的路徑

3、執行

在Flutter安裝目錄的flutter檔案下找到flutter_console.bat,雙擊執行並啟動flutter命令列,接下來,你就可以在Flutter命令列執行flutter命令了。

二、配置

1、修改環境變數

在“使用者變數”下檢查是否有名為“Path”的條目:

如果該條目存在, 追加 flutter\bin的全路徑,使用 ; 作為分隔符.

如果條目不存在, 建立一個新使用者變數 Path ,然後將 flutter\bin的全路徑作為它的值.

path加上flutter

image.png

在“使用者變數”下檢查是否有名為”PUB_HOSTED_URL”和”FLUTTER_STORAGE_BASE_URL”的條目,如果沒有,也新增它們。

image.png

image.png 重啟Windows以應用此更改

2、執行 flutter doctor

開啟一個新的命令提示符或PowerShell視窗並執行以下命令以檢視是否需要安裝任何依賴項來完成安裝:

flutter doctor

image.png

編譯器

一、安裝

從上面執行flutter doctor的提示來看,flutter常用的編譯器是IDE、Android Studio和vscode,一般情況下最好是都安裝上,便於後期除錯。

Android Studio

www.android-studio.org/

二、配置編譯器

就以vscode為例,配置編譯器,開始我們的第一個專案

啟動 VS Code

呼叫 View>Command Palette…

輸入 ‘install’, 然後選擇 Extensions: Install Extension action

在搜尋框輸入 flutter , 在搜尋結果列表中選擇 ‘Flutter’, 然後點選 Install

選擇 ‘OK’ 重新啟動 VS Code

hello Flutter

一、搭建一個基礎的flutter服務

1、啟動 VS Code

2、呼叫 View>Command Palette…

3、輸入 ‘flutter’, 然後選擇 ‘Flutter: New Project’ action

4、輸入 Project 名稱 (如myapp), 然後按Enter鍵

5、指定放置專案的位置,然後按藍色的確定按鈕

6、等待專案建立繼續,並顯示main.dart檔案

image.png

二、執行服務

1、確保在VS Code的右下角選擇了目標裝置

2、按 F5 鍵或呼叫Debug>Start Debugging

3、等待應用程式啟動

4、如果一切正常,在應用程式建成功後,您應該在您的裝置或模擬器上看到應用程式:

image.png

熱更新

和vue-cli一樣,修改完儲存後自動熱更新

建立 Flutter app

一、基礎版

在這個示例中,你將主要編輯Dart程式碼所在的 lib/main.dart 檔案,

1、替換 lib/main.dart.

刪除lib / main.dart中的所有程式碼,然後替換為下面的程式碼,它將在螢幕的中心顯示“Hello World”.

2、執行應用程式,你應該看到如下介面.

image.png

分析

本示例建立一個Material APP。Material是一種標準的移動端和web端的視覺設計語言。 Flutter提供了一套豐富的Material widgets。

main函式使用了(=>)符號, 這是Dart中單行函式或方法的簡寫。

該應用程式繼承了 StatelessWidget,這將會使應用本身也成為一個widget。 在Flutter中,大多數東西都是widget,包括對齊(alignment)、填充(padding)和佈局(layout)

Scaffold 是 Material library 中提供的一個widget, 它提供了預設的導航欄、標題和包含主螢幕widget樹的body屬性。widget樹可以很複雜。

widget的主要工作是提供一個build()方法來描述如何根據其他較低階別的widget來顯示自己。

本示例中的body的widget樹中包含了一個Center widget, Center widget又包含一個 Text 子widget。 Center widget可以將其子widget樹對其到螢幕中心。

二、使用外部包(package)

在這一步中,您將開始使用一個名為english_words的開源軟體包 ,其中包含數千個最常用的英文單詞以及一些實用功能.

您可以 在pub.dartlang.org上找到english_words軟體包以及其他許多開源軟體包

1、安裝

pubspec檔案管理Flutter應用程式的assets(資源,如圖片、package等)。 在pubspec.yaml中,將english_words(3.1.0或更高版本)新增到依賴項列表:

image.png

2、引入

import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart';

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

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final wordPair = new WordPair.random(); return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Center( //child: new Text('Hello World'), child: new Text(wordPair.asPascalCase), ), ), ); } }

3、啟動

如果應用程式正在執行,請使用熱過載按鈕 (lightning bolt icon) 更新正在執行的應用程式。每次單擊熱過載或儲存專案時,都會在正在執行的應用程式中隨機選擇不同的單詞對。 這是因為單詞對是在 build 方法內部生成的。每次MaterialApp需要渲染時或者在Flutter Inspector中切換平臺時 build 都會執行.

三、新增一個 有狀態的部件(Stateful widget)

Stateless widgets 是不可變的, 這意味著它們的屬性不能改變 - 所有的值都是最終的.

Stateful widgets 持有的狀態可能在widget生命週期中發生變化. 實現一個 stateful widget 至少需要兩個類:

一個 StatefulWidget類。 一個 State類。 StatefulWidget類本身是不變的,但是 State類在widget生命週期中始終存在. 在這一步中,您將新增一個有狀態的widget-RandomWords,它建立其State類RandomWordsState。State類將最終為widget維護建議的和喜歡的單詞對。

1、新增一個RandomWords widget

class RandomWords extends StatefulWidget { @override createState() => new RandomWordsState(); }

2、新增 RandomWordsState 類.

該應用程式的大部分程式碼都在該類中, 該類持有RandomWords widget的狀態。這個類將儲存隨著使用者滾動而無限增長的生成的單詞對, 以及喜歡的單詞對,使用者通過重複點選心形 ❤️ 圖示來將它們從列表中新增或刪除。

class RandomWordsState extends State { }

3、新增一個build方法

class RandomWordsState extends State { @override Widget build(BuildContext context) { final wordPair = new WordPair.random(); return new Text(wordPair.asPascalCase); } }

4、掛在到myApp上

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Center( //child: new Text(wordPair.asPascalCase), child: new RandomWords(), ), ), ); } }

5、執行

[圖片上傳失敗...(image-1a42f-1616398520798)]

四、建立一個無限滾動ListView

在這一步中,您將擴充套件(繼承)RandomWordsState類,以生成並顯示單詞對列表。 當使用者滾動時,ListView中顯示的列表將無限增長。 ListView的builder工廠建構函式允許您按需建立一個懶載入的列表檢視。

1、向RandomWordsState類中新增一個_suggestions列表以儲存建議的單詞對。

該變數以下劃線(_)開頭,在Dart語言中使用下劃線字首識別符號,會強制其變成私有的。

class RandomWordsState extends State { final _suggestions = [];

final _biggerFont = const TextStyle(fontSize: 18.0); ... }

2、向RandomWordsState類新增一個 _buildSuggestions() 函式. 此方法構建顯示建議單詞對的ListView。

ListView類提供了一個builder屬性,itemBuilder 值是一個匿名回撥函式, 接受兩個引數- BuildContext和行迭代器i。迭代器從0開始, 每呼叫一次該函式,i就會自增1,對於每個建議的單詞對都會執行一次。該模型允許建議的單詞對列表在使用者滾動時無限增長。

class RandomWordsState extends State { ... Widget _buildSuggestions() { return new ListView.builder( padding: const EdgeInsets.all(16.0), // 對於每個建議的單詞對都會呼叫一次itemBuilder,然後將單詞對新增到ListTile行中 // 在偶數行,該函式會為單詞對新增一個ListTile row. // 在奇數行,該函式會新增一個分割線widget,來分隔相鄰的詞對。 // 注意,在小螢幕上,分割線看起來可能比較吃力。 itemBuilder: (context, i) { // 在每一列之前,新增一個1畫素高的分隔線widget if (i.isOdd) return new Divider();

    // 語法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整),比如i為:1, 2, 3, 4, 5
    // 時,結果為0, 1, 1, 2, 2, 這可以計算出ListView中減去分隔線後的實際單詞對數量
    final index = i ~/ 2;
    // 如果是建議列表中最後一個單詞對
    if (index >= _suggestions.length) {
      // ...接著再生成10個單詞對,然後新增到建議列表
      _suggestions.addAll(generateWordPairs().take(10));
    }
    return _buildRow(_suggestions[index]);
  }
);
複製程式碼

} }

3、對於每一個單詞對,_buildSuggestions函式都會呼叫一次_buildRow。

這個函式在ListTile中顯示每個新詞對,這使您在下一步中可以生成更漂亮的顯示行

在RandomWordsState中新增一個_buildRow函式 :

class RandomWordsState extends State { ...

Widget _buildRow(WordPair pair) { return new ListTile( title: new Text( pair.asPascalCase, style: _biggerFont, ), ); } }

4、更新RandomWordsState的build方法以使用_buildSuggestions(),而不是直接呼叫單詞生成庫。

class RandomWordsState extends State { ... @override Widget build(BuildContext context) { return new Scaffold ( appBar: new AppBar( title: new Text('Startup Name Generator'), ), body: _buildSuggestions(), ); } ... }

5、更新MyApp的build方法。

從MyApp中刪除Scaffold和AppBar例項。 這些將由RandomWordsState管理,這使得使用者在下一步中從一個螢幕導航到另一個螢幕時, 可以更輕鬆地更改導航欄中的的路由名稱。

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Startup Name Generator', home: new RandomWords(), ); } }

五、互動版

在這一步中,您將為每一行新增一個可點選的心形 ❤️ 圖示。當使用者點選列表中的條目,切換其“收藏”狀態時,將該詞對新增到或移除出“收藏夾”。

1、新增一個 _saved Set(集合) 到RandomWordsState。這個集合儲存使用者喜歡(收藏)的單詞對。 在這裡,Set比List更合適,因為Set中不允許重複的值。

class RandomWordsState extends State { final _suggestions = [];

final _saved = new Set();

final _biggerFont = const TextStyle(fontSize: 18.0); ... }

2、在 _buildRow 方法中新增 alreadySaved來檢查確保單詞對還沒有新增到收藏夾中。

Widget _buildRow(WordPair pair) { final alreadySaved = _saved.contains(pair); ... }

3、同時在 _buildRow()中, 新增一個心形 ❤️ 圖示到 ListTiles以啟用收藏功能。接下來,你就可以給心形 ❤️ 圖示新增互動能力了。

Widget _buildRow(WordPair pair) { final alreadySaved = _saved.contains(pair); return new ListTile( title: new Text( pair.asPascalCase, style: _biggerFont, ), trailing: new Icon( alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), ); }

4、重新啟動應用。你現在可以在每一行看到心形❤️圖示️,但它們還沒有互動。

5、在 _buildRow中讓心形❤️圖示變得可以點選。如果單詞條目已經新增到收藏夾中, 再次點選它將其從收藏夾中刪除。當心形❤️圖示被點選時,函式呼叫setState()通知框架狀態已經改變。

Widget _buildRow(WordPair pair) { final alreadySaved = _saved.contains(pair); return new ListTile( title: new Text( pair.asPascalCase, style: _biggerFont, ), trailing: new Icon( alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), onTap: () { setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, ); }

image.png

寫在最後

關於搭建基礎的flutter環境,非常簡單,只要你照著官網一步一步往下走,基本不會遇到什麼問題。

相關文章