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

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

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

image.png

什麼是flutter?

官方定義:

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

安裝與配置

1、安裝

要完整的跑起來一個flutter項目,大概須要下面這些工具:

一、Android Studio + avdandroid

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

三、vscode、webstorm、IDEA(這個看我的喜愛)vue-cli

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

五、Android SDK(這個直接在Android Studio裏面安裝)react-native

六、須要各類模擬器(推薦pixel 和Xcode,一個安卓一個iOS)android-studio

關於java JDK和Android Studio 安裝包,若是須要的話能夠私信markdown

一、下載flutter SDK

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

二、解壓安裝包

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

三、運行

在Flutter安裝目錄的flutter文件下找到flutter_console.bat,雙擊運行並啓動flutter命令行,接下來,你就能夠在Flutter命令行運行flutter命令了。

2、配置

一、修改環境變量

在「用戶變量」下檢查是否有名爲「Path」的條目:

若是該條目存在, 追加 flutter\bin的全路徑,使用 ; 做爲分隔符.

若是條目不存在, 建立一個新用戶變量 Path ,而後將 flutter\bin的全路徑做爲它的值.

path加上flutter

image.png

在「用戶變量」下檢查是否有名爲」PUB_HOSTED_URL」和」FLUTTER_STORAGE_BASE_URL」的條目,若是沒有,也添加它們。

image.png

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

二、運行 flutter doctor

打開一個新的命令提示符或PowerShell窗口並運行如下命令以查看是否須要安裝任何依賴項來完成安裝:

flutter doctor

image.png

編譯器

1、安裝

從上面執行flutter doctor的提示來看,flutter經常使用的編譯器是IDE、Android Studio和vscode,通常狀況下最好是都安裝上,便於後期調試。

Android Studio

www.android-studio.org/

2、配置編譯器

就以vscode爲例,配置編譯器,開始咱們的第一個項目

啓動 VS Code

調用 View>Command Palette…

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

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

選擇 ‘OK’ 從新啓動 VS Code

hello Flutter

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

一、啓動 VS Code

二、調用 View>Command Palette…

三、輸入 ‘flutter’, 而後選擇 ‘Flutter: New Project’ action

四、輸入 Project 名稱 (如myapp), 而後按回車鍵

五、指定放置項目的位置,而後按藍色的肯定按鈕

六、等待項目建立繼續,並顯示main.dart文件

image.png

2、運行服務

一、確保在VS Code的右下角選擇了目標設備

二、按 F5 鍵或調用Debug>Start Debugging

三、等待應用程序啓動

四、若是一切正常,在應用程序建成功後,您應該在您的設備或模擬器上看到應用程序:

image.png

熱更新

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

建立 Flutter app

1、基礎版

在這個示例中,你將主要編輯Dart代碼所在的 lib/main.dart 文件,

一、替換 lib/main.dart.

刪除lib / main.dart中的全部代碼,而後替換爲下面的代碼,它將在屏幕的中心顯示「Hello World」.

二、運行應用程序,你應該看到以下界面.

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樹對其到屏幕中心。

2、使用外部包(package)

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

您能夠 在pub.dartlang.org上找到english_words軟件包以及其餘許多開源軟件包

一、安裝

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

image.png

二、引入

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), ), ), ); } }

三、啓動

若是應用程序正在運行,請使用熱重載按鈕 (lightning bolt icon) 更新正在運行的應用程序。每次單擊熱重載或保存項目時,都會在正在運行的應用程序中隨機選擇不一樣的單詞對。 這是由於單詞對是在 build 方法內部生成的。每次MaterialApp須要渲染時或者在Flutter Inspector中切換平臺時 build 都會運行.

3、添加一個 有狀態的部件(Stateful widget)

Stateless widgets 是不可變的, 這意味着它們的屬性不能改變 - 全部的值都是最終的.

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

一個 StatefulWidget類。 一個 State類。 StatefulWidget類自己是不變的,可是 State類在widget生命週期中始終存在. 在這一步中,您將添加一個有狀態的widget-RandomWords,它建立其State類RandomWordsState。State類將最終爲widget維護建議的和喜歡的單詞對。

一、添加一個RandomWords widget

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

二、添加 RandomWordsState 類.

該應用程序的大部分代碼都在該類中, 該類持有RandomWords widget的狀態。這個類將保存隨着用戶滾動而無限增加的生成的單詞對, 以及喜歡的單詞對,用戶經過重複點擊心形 ❤️ 圖標來將它們從列表中添加或刪除。

class RandomWordsState extends State { }

三、添加一個build方法

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

四、掛在到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(), ), ), ); } }

五、運行

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

4、建立一個無限滾動ListView

在這一步中,您將擴展(繼承)RandomWordsState類,以生成並顯示單詞對列表。 當用戶滾動時,ListView中顯示的列表將無限增加。 ListView的builder工廠構造函數容許您按需創建一個懶加載的列表視圖。

一、向RandomWordsState類中添加一個_suggestions列表以保存建議的單詞對。

該變量如下劃線(_)開頭,在Dart語言中使用下劃線前綴標識符,會強制其變成私有的。

class RandomWordsState extends State { final _suggestions = [];

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

二、向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]);
  }
);
複製代碼

} }

三、對於每個單詞對,_buildSuggestions函數都會調用一次_buildRow。

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

在RandomWordsState中添加一個_buildRow函數 :

class RandomWordsState extends State { ...

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

四、更新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(), ); } ... }

五、更新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(), ); } }

5、交互版

在這一步中,您將爲每一行添加一個可點擊的心形 ❤️ 圖標。當用戶點擊列表中的條目,切換其「收藏」狀態時,將該詞對添加到或移除出「收藏夾」。

一、添加一個 _saved Set(集合) 到RandomWordsState。這個集合存儲用戶喜歡(收藏)的單詞對。 在這裏,Set比List更合適,由於Set中不容許重複的值。

class RandomWordsState extends State { final _suggestions = [];

final _saved = new Set();

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

二、在 _buildRow 方法中添加 alreadySaved來檢查確保單詞對尚未添加到收藏夾中。

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

三、同時在 _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, ), ); }

四、從新啓動應用。你如今能夠在每一行看到心形❤️圖標️,但它們尚未交互。

五、在 _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環境,很是簡單,只要你照着官網一步一步往下走,基本不會遇到什麼問題。

相關文章
相關標籤/搜索