iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 6
3
Mobile Development

Flutter---Google推出的跨平台框架,Android、iOS一起搞定系列 第 6

【Flutter基礎概念與實作】 Day6–Flutter Hello World!

今天開始我們正式進入Flutter的世界,大家應該都有安裝好Flutter SDK並選擇自己習慣的IDE了吧(若還沒設定好,可以參考Day1的安裝教學)。


更新Flutter

在開始之前,我們更新一下Flutter並再次確認一下全都設定好了。
開啟PowerShell或是cmd,輸入flutter upgrade
最後看見No issues found!就OK了。


開新專案

要開啟一個新的專案你可以選擇使用cmd的方式輸入flutter create [project_name]或是用Android Studio來新增。
這裡我們使用Android Studio來建立。

如果有照著Day1的教學去安裝Flutter的Plugin,應該會在開啟介面時看到Start a new Flutter project,點選它進入下一步。

選擇Flutter Application

幫專案取一個名字(開頭需是英文小寫)
確認Flutter SDK 路徑指向當初安裝的目錄
都沒問題就點Next

設定package name,如果之後App有要上架到app store才需要注意,這裡就直接用預設的即可。
點選Finsh讓Android Studio幫我們初始化一個專案。

第一次開啟可能會花點時間(視電腦效能而定),最後會看到下圖畫面,專案成功建立囉。

你可以開啟模擬器並執行看看程式,會出現一個簡單的App,畫面上有一個Button以及顯示你按了幾下的Text。

若一切都運作正常,那麼可以先把模擬器縮小,先來認識Flutter的檔案結構,程式碼的部分待會再來說明。


Flutter的檔案結構

首先可以看見幾個資料夾android、ios、、build、lib以及test
他們分別的用途是:
android:與Android相關的程式碼以及設定,例如要開啟讀取或寫入權限就要到裡面的AndroidManifest填寫。

ios:同樣的ios資料夾就是放和iOS相關的程式與以及設定。

build:不會使用到的資料夾,裡面存放系統產生的檔案,

lib:放Flutter程式碼的資料夾,之後寫的程式碼檔案都會放在這,目前裡面只有剛剛執行的main.dart

test:放測試用程式碼,目前裡面只有一個檔案,用來測試程式是否有按照預期方式執行。之後會排2天時間來寫簡單的測試。


其他檔案的用途分別是:
.gitignore:若你有使用版本控制軟體但有些不重要的檔案或是機密檔案不能傳上去,就在這裡註明忽略他們。

.metadata:IDE用來追蹤flutter project用

.package:管理第三方或是IDE package的檔案,會自動產生與更新內容

.pubspec.lock:保存目前pubspec.yaml的資訊,確保其他人使用時能夠下載到同樣版本的packages

.pubspec.yaml:我們唯一會去修改的檔案,例如使用第三方package,或要引入媒體檔案等等


First Flutter App

看完各資料夾以及檔案的用途後,希望你對於Flutter的架構有初步的認識。現在就來看看Flutter版Hello World是如何運作的吧。


開啟lib/main.dart

你會看到一大堆的註解跟你解釋每個元件的用途,這是因為Flutter是開源的專案,因此它的文件都有很完善的註解說明。

如果不想看英文解釋,我在下面也會介紹每個區域的程式碼用途。


刪除註解

按下ctrl + R輸入/*([\S\s]+?),勾選右方Regex使用正規式搜尋並將Filter勾選成In Comments,按下Replace all
最後用ctrl + alt + L排版程式碼。


程式的入口

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

還記得前幾天練習Dart語法時程式都是從main()進入的嗎?Flutter也是從main function開始,並執行runApp這個function。
runApp()會將給定的widget填滿整個螢幕,這裡傳給它名為MyApp的widget物件。

如果你想測試填滿的效果是如何,可以把其他程式碼刪除並替換成以下內容

import 'package:flutter/material.dart';

void main() => runApp(Center(
        child: Text(
      'Hello Flutter',
      textDirection: TextDirection.ltr,
    )));

簡單解釋一下這段程式碼

Center是一個widget,能夠讓他的child(這裡的Text widget)置中
Text也是一個widget,用來顯示文字,這裡需額外設定它的文字方向為由左至右(ltr),不然會跳出error

最後就會顯示如圖一樣的畫面,文字在螢幕的正中間,表示runApp()確實會將給定的widget填滿整個螢幕。


MyApp Class

回到原本的程式碼,接著來看MyApp這個class,它繼承自StatelessWidget,表示這個widget在被建立之後就固定住,不會再更改。剛剛使用的Text也屬於這一類。

當widget被建立時會呼叫build這個function,回傳的就是要顯示的內容。

它回傳的MaterialApp有三個參數title、theme以及home,來試著修改他們看看效果如何。

修改後只要使用ctrl + S或是點選上方的閃電圖案的hot reload,就能快速更新App的畫面

title:這個標題在App是看不到的,而是會在手機管理App程式的地方。

theme:介面的顏色風格,修改成其他顏色看看有什麼變化。

home:App的首頁,接受的值為widget物件,這裡傳入MyHomePage這個widget。


MyHomePage

和MyApp不同,MyHomePage繼承自StatefulWidget,聰明的你應該知道Stateful的意思就是它的狀態會隨著時間做改變。

因此可以看到有createState這個function,就是用來建立及控管它的狀態的。


_MyHomePageState

名稱前面的_,代表這是個private class。

接著是build function,當狀態更新時會使用build重新繪製widget,回傳值是一個widget。

這裡回傳了Scaffold widget,Scaffold包含了常用元件的如AppBar、NavigationBar、Drawer等等,可以很快地建立介面(明天會提到如何使用它們)。
使用到的AppBar、body、floatingActionButton這三個參數,就留給你自己玩看看。

要提的重點在於FloatingActionButton中onPressed使用的_incrementCounter function

void _incrementCounter() {
    setState(() {
      _counter++;
    });
}

裡頭呼叫的setState就是Stateful的重點所在,它會去通知框架說我的狀態改變了(counter值),要求重新繪製widget,因此App畫面就會被更新。


今日總結

今天我們建立了一個新專案,認識了Flutter框架的檔案架構並且瞭解App的運作方式。

相信你已經有體會到Flutter核心特色Everything’s a widget是什麼意思,今天碰到的無論是MyApp、MyHomePage、Text或是Button全都是widget,App介面就是由一棵巨大的widget Tree所組成,只要熟用widget就能建構出美觀的UI介面。

所以明天就來認識基礎的widget有哪些,以及該如何使用它們呢。


上一篇
【Flutter基礎概念與實作】 Day5–Dart Language(3)
下一篇
【Flutter基礎概念與實作】 Day7–Flutter Basic Widgets
系列文
Flutter---Google推出的跨平台框架,Android、iOS一起搞定30

2 則留言

0
imakou
iT邦新手 5 級 ‧ 2019-10-20 15:03:06

請問能否在這裡稍微講解

class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key}) : super(key: key);

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {...}

這個閱讀順序應該是如何呢?以及 @override 的作用在這邊是什麼呢?

謝謝您?

看更多先前的回應...收起先前的回應...

MyStatefulWidget({Key key}) : super(key: key);
這一行是MyStatefulWidget類別的「建構子」,當MyStatefulWidget物件被建立時會首先觸發,細節可以參考Day5的class介紹
我猜你可能也對於「Key」這個部分感到疑惑,可以參考官方介紹Key使用方法的影片

@override表示要覆寫他的父類別StatefulWidget內createState這個方法。
可以參考這篇介紹Java override的文章,這部分Java和Dart是相同的。

imakou iT邦新手 5 級 ‧ 2019-10-20 16:16:19 檢舉

您好,
非常謝謝回應。

所以是否能理解就是
class MyStatefulWidget 的 父方法 createState() 在這個class裏已經被下面的 _MyStatefulWidgetState 給取代了,真正實作發生在 _MyStatefulWidgetState 裡面。

但是這裡又有一個疑惑就是為什麼是這樣
extends State<MyStatefulWidget>
繼承State父類別,但是限定必須是MyStatefulWidget 這裡我理解起來有點不通順

謝謝您

首先_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
並不是您說的被_MyStatefulWidgetState取代,而是當createState這個方法被呼叫的時候,會回傳_MyStatefulWidgetState這個物件用來記錄及儲存目前Widget的狀態。

而_MyStatefulWidgetState被限定於只能給MyStatefulWidget使用。

這一篇文章的2-2章節有介紹StatefulWidget的生命週期,看完或許對你有幫助

0
eric19740521
iT邦新手 4 級 ‧ 2020-09-13 04:29:11

請問以下的訊息???是程式問題嗎???
我用flutter產生的專案範例...


Launching lib\main.dart on sdk gphone x86 in debug mode...
Running Gradle task 'assembleDebug'...
✓ Built build\app\outputs\flutter-apk\app-debug.apk.
Waiting for sdk gphone x86 to report its views...
Debug service listening on ws://127.0.0.1:7670/ZoY8Owc9jJQ=/ws
Syncing files to device sdk gphone x86...
D/EGL_emulation( 8529): eglMakeCurrent: 0xe99e7060: ver 3 0 (tinfo 0xe9d3c450)
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 
D/skia    ( 8529): Shader compilation error
D/skia    ( 8529): ------------------------
D/skia    ( 8529): Errors:
D/skia    ( 8529): 

我要留言

立即登入留言