Google Flutter From Scratch:使用小部件構建應用程序

Flutter正迅速成為開發跨平台移動應用程序的最流行框架之一。今天,大多數Android和iOS開發人員開始認為,它是一種比其他跨平台框架(如React Native和NativeScript)更快,更具面向未來的替代方案。

谷歌本身不遺餘力地吸引更多開發者加入。例如,Google I / O今年有幾個深入的會議,專註於使用它開發符合Material Design標準的應用程序。在其中一次會議中,Google還宣布Flutter將成為Material Design的一流平台。

在本系列教程中,我將幫助您掌握使用Flutter開發Android應用程序的基礎知識。在本系列開始的教程中,我將重點關注Flutter小部件,這是所有Flutter應用程序的構建塊。

先決條件

要充分利用這個系列,您需要:

  • 最新版本的Android Studio
  • 運行Android API等級21或更高版本的設備或模擬器

1.配置Android Studio

安裝了一些輕量級插件後,您可以使用Android本地Android應用程序開發人員最熟悉的Android Studio來開發Flutter應用程序。

首先啟動Android Studio,然後 在歡迎屏幕中選擇配置>插件選項。

在彈出的對話框中,按「 瀏覽存儲庫」 按鈕並搜索Flutter插件。

瀏覽存儲庫對話框

找到插件後,按「 安裝」 按鈕。此時,系統會詢問您是否還要安裝Dart插件。按 繼續。

插件依賴項對話框

安裝 完兩個插件後,按「 重啟Android Studio」按鈕完成配置。

2.創建一個新項目

重啟後,您將能夠 在Android Studio歡迎屏幕上看到「 啟動新的Flutter項目」按鈕。按此按鈕開始創建您的第一個Flutter項目。

在下一個屏幕上,選擇Flutter Application 選項,然後按Next

創建Flutter項目對話框

您現在將看到一個表單,詢問有關Flutter應用程序的各種詳細信息,例如其名稱和位置。確保在所有欄位中鍵入有效值。

Flutter項目配置對話框

Flutter插件不與Flutter SDK捆綁在一起。因此,您必須單獨安裝SDK。您現在可以通過按「 安裝SDK」 按鈕來執行此操作。

根據Internet連接的速度,安裝可能需要相當長的時間才能完成。成功後,您將能夠按「 下一步」 按鈕完成項目設置。

3.添加入口點

在本教程中,您將在lib / main.dart 文件中編寫代碼。默認情況下,它將包含一些您不需要的示例代碼。所以在繼續之前刪除所有內容。

Flutter框架使用Dart編程語言,這是一種易於學習的語言,其語法與Java和C的語法非常相似。因此,像大多數獨立的Java和C程序一樣,Flutter應用程序也需要一個main() 函數,一個特殊的函數,作為應用程序的入口點。

因此,將以下代碼添加到main.dart 文件中:

void main() {
// TO DO
}

此時,您可以按 Shift-F10 來構建和運行應用程序。如果您在前面的步驟中沒有遇到任何錯誤,您應該會看到該應用在您的設備上顯示空白的白色畫布。

4.使用無狀態小部件

所有Flutter應用程序都由一個或多個小部件組成,類的實例允許您在屏幕上繪製文本和圖像。通常,您不必從頭開始編寫任何低級小部件,因為該框架附帶了各種預製的,漂亮的小部件,這些小部件遵循Android和iOS平台的設計語言。

為了能夠在您的應用程序中使用基本小部件,請widgets 通過在main.dart 文件的開頭添加以下代碼來導入庫:

import package:flutter/widgets.dart;

您可以創建的最簡單的小部件是無狀態小部件。正如您可能已經猜到的那樣,它們沒有與之相關的狀態,因此是靜態的。它們非常適合顯示標籤,標題和其他UI元素,其內容在應用程序運行時不太可能發生變化。要創建無狀態窗口小部件,必須擴展StatelessWidget 該類並覆蓋其build() 方法。以下示例代碼顯示了如何:

class MyFirstWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// More code here
}
}

正如您在上面的代碼中看到的,該build() 方法必須返回一個Widget 對象。您可以自由選擇並返回Flutter提供的數十種預製小部件中的任何一種。例如,如果要顯示一行文本,可以創建並返回一個Text 小部件,如下所示:

return Text("This is nice!",
textDirection: TextDirection.ltr);

請注意,您必須始終記住在使用Text 窗口小部件時指定文本的方向 。

但是,如果您立即運行該應用程序,您將無法看到該文本。那是因為你還沒有實例化你的無狀態小部件。所以轉到main() 方法,在其中實例化小部件,並將其傳遞給runApp() 方法。這是如何做:

runApp(new MyFirstWidget());

在您添加上述代碼並保存項目的那一刻,Android Studio應該會自動在您的設備上熱重新載入應用,以便您查看文本。

應用程序顯示文本

如果要顯示圖像而不是文本,可以Text 使用Image 類的build() 方法中的窗口小部件替換窗口小部件。以下代碼顯示如何創建Image 下載並顯示遠程圖像的窗口小部件:

`return` `Image.network(`

`"[https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg](https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg)"``);`

再次保存項目時,您應該在設備上看到類似的內容:

應用程序顯示圖像

5.創建小部件樹

所有Flutter應用程序都可以被視為小部件樹。您在上一步中創建的應用程序是一個只包含一個小部件的小部件樹。但是,使用TextImage 窗口小部件作為窗口小部件樹的頂部元素並不是一個好主意,因為您將無法向它們添加任何子窗口小部件。

Flutter提供了幾個可以作為其他小部件容器的小部件。最常用的是RowColumn 小部件。正如他們的名字所暗示的那樣, Row 小部件允許您將多個小部件放在一起,並且Column 小部件可以幫助您將小部件放在 另一個之下。在創建更深層的窗口小部件樹時,它們是必不可少的。

以下代碼顯示如何使用Column 窗口小部件創建具有兩個子窗口的窗口小部件樹:Text窗口小部件和Image 窗口小部件。

`Text myText = Text(``"This is a nice photo!"``,`

`textDirection: TextDirection.ltr);`

`Image myImage = Image.network(`

`"[https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg](https://images.pexels.com/photos/1168940/pexels-photo-1168940.jpeg)"``);`

`return` `Column(`

`children: <Widget>[myText, myImage]`

`);`

該應用程序現在應該如下所示:

應用程序顯示兩個小部件

此外,還有一些小部件可以幫助您更好地定位單個小部件。例如,Center 窗口小部件可幫助您集中窗口小部件。同樣,Container 窗口小部件允許您向窗口小部件添加填充和邊距。

以下代碼向您展示如何Column通過將您剛創建的窗口小部件嵌入窗口小部件來居中它Center

return Center(child: Column(
children: <Widget>[myText, myImage],
mainAxisSize: MainAxisSize.min
)
);

在上面的代碼中,請注意Column 窗口小部件使用一個名為的附加屬性 mainAxisSize,其值設置為min。這是必要的,因為在對列居中之前,必須使其高度等於其所有子節點的高度之和。如果沒有該屬性,Column 窗口小部件將與設備的屏幕一樣大,並且Center 窗口小部件將不會對其產生任何影響。

6.使用Material Design Widgets

在此期間,您一直在使用作為widgets 庫的一部分的基本小部件。Flutter有一個名為的替代庫material,它提供了Material Design小部件。要在您的應用程序中使用它,請使用以下內容替換導入widgets 庫的語句:

import package:flutter/material.dart;

接下來,要將Material Design樣式應用於窗口小部件,您必須MaterialApp 在窗口小部件樹的頂部放置一個 窗口小部件。您還必須將先前創建的所有小部件嵌入到窗口小Scaffold 部件中,該窗口小部件可用作窗口小部件的主屏幕 MaterialApp 。

此外,由於大多數Material Design應用程序都有應用欄,因此您可以選擇將Scaffold 小部件appBar 屬性設置為新AppBar 小部件。

以下代碼向您展示如何簡潔地完成所有操作:

return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("My App")),
body: Center(
child: Column(
children: <Widget>[myText, myImage],
mainAxisSize: MainAxisSize.min
),
)
)
);

該應用程序現在應該看起來好多了。

應用程序顯示Material Design小部件

7.使用有狀態小部件

無狀態小部件是不可變的。使用您在前面的步驟中編寫的代碼,沒有簡單的方法來修改Text 窗口小部件或Image 窗口小部件的內容。為什麼?因為Flutter框架更喜歡反應式編程而不是命令式編程。因此,它的大多數小部件都沒有可以在運行時更新其內容的setter方法。例如,Text 窗口小部件沒有setText() 允許您更改其顯示文本的方法。

另一方面,有狀態小部件是可變的,儘管不是直接的。他們依靠 State 對象來決定在任何給定實例中應該顯示什麼。因此,只要State 對象發生更改,框架就會自動更新連接到它的任何有狀態窗口小部件的內容。

要創建有狀態窗口小部件,必須擴展StatefulWidget 該類並覆蓋其 createState() 方法。

class MySecondWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TO DO
}
}

接下來,您必須創建一個新的自定義State 類,其中包含構成有狀態窗口小部件狀態的變數。此外,在類中,您必須重寫 build() 方法以返回窗口小部件樹。

以下代碼顯示如何創建State 包含名為的單個變數的類url:

`class` `MyState` `extends` `State<MySecondWidget> {`

`String url =` `"[https://source.unsplash.com/random/800x600](https://source.unsplash.com/random/800x600)"``;`

`// A random image from Unsplash`

`@override`

`Widget build(BuildContext context) {`

`// More code here`

`}`

`}`

為了一個具體的例子,我們現在創建一個Material Design窗口小部件樹Image ,其中包含一個顯示隨機圖像的RaisedButton 窗口小部件和一個窗口小部件,用戶可以按這個窗口小部件來載入新的隨機圖像。以下代碼顯示了如何:

return MaterialApp(
home: Scaffold(
body: Center(
child:Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RaisedButton(
child: Text("Press Me"),
onPressed: changeURL,
),
Image.network(url)
]
)
)
)
);

請注意,Image 窗口小部件的構造函數現在將url 變數作為其輸入,而不是字元串文字。這允許框架在Image 繪製窗口小部件時使用變數的最新值。

另請注意,RaisedButton 窗口小部件具有onPressed 指向名為的事件偵聽器的屬性changeURL()。該方法尚不存在,因此請創建它。

void changeURL() {
// More code here
}

當然,在方法中,您必須更改url 變數的值。但是,您不應該直接更改它。如果這樣做,Flutter框架將不會收到有關更改的通知。要正確更新有狀態窗口小部件的狀態,必須始終在setState() 方法內進行所有更改。

目前,為了顯示隨機圖像,我建議您使用Unsplash Source 服務。從中下載隨機圖像所需要做的就是向其URL發出HTTP請求並向其傳遞唯一的查詢字元串。

以下代碼顯示如何使用時間戳構造唯一查詢字元串:

`setState(() {`

`url =` `"[https://source.unsplash.com/random/800x600/?](https://source.unsplash.com/random/800x600/?)"` `+`

`"q=${new DateTime.now().millisecondsSinceEpoch}"``;`

`});`

此時,您的自定義State 類已準備就緒。接下來需要做的就是實例化它並從createState() 有狀態小部件的方法返回它。

runApp(new MyFirstWidget());

如果您將有狀態窗口小部件的實例傳遞給runApp()方法,重新載入應用程序,並按幾次按鈕,您應該會看到它每次都顯示一張新照片。

應用程序顯示隨機照片

結論

您現在知道如何在Flutter應用程序中使用無狀態和有狀態的小部件。您還學習了如何將Material Design主題應用於它們,動態更改其內容並使它們具有交互性。

值得注意的是,Flutter不使用任何移動平台的本機小部件。它使用名為Skia的高性能2D圖形引擎自行繪製所有小部件,該引擎廣泛使用GPU。因此,Flutter應用程序通常以接近60 fps的速度運行,並且感覺非常流暢和響應。

知乎關注我:私信回復「資料」獲取高級UI、Gradle、RxJava、小程序、Hybrid、移動架構、React Native、性能優化等技術教程!架構師課程、NDK、混合式開發全方 面的 Android高級實踐技術講解性能優化架構思維導圖,和BATJ面試題及答案。


推薦閱讀:

TAG:Android | 程序員 | Android開發 |