初探 Flutter — 實作一個 Widget 開始

Engine Bai
4 min readSep 6, 2021

--

最近 FunNow 開始做了一個 App 新專案,要使用 Flutter 做開發,Flutter 之前 1.0 正式版發怖後就有開始在多少學一點,有 Android 開發經驗轉過去是蠻容易上手的,這篇想要示範一個新專案上所用到十分簡單的客製化元件以及講解一些 Dart 基礎語法和 Container 常用用法,希望多少能給大家帶來一些幫助。

UI Requirements

FunBook + FunNow App

今天要示範的是一個簡單的純文字標籤,可以有底色或者框線,可以指定文字大小、顏色、框線寬度、框線顏色。

程式實作

Stateful v.s. Stateless

在 Flutter 世界,所有 UI 元件都是 Widgets,而 Widget 有分 Stateful v.s. Stateless,這兩者差異在於前者會因為使用者操作而保有不同的狀態,進而改變元件呈現的外觀或者樣子,像是輸入框、可選取的選單列表…等;而 Stateless 則不會有不同狀態,在程式裡面給定一個值,給這個元件就照這個值顯示,像是文字、圖片…等,而我們今天的簡單元件就屬於 Stateless。

Properties

我們宣告幾個屬性來讓我們客製化我們的標籤:

這邊兩個小重點:

  1. 屬性宣告為 final 是指 Runtime Constant,表示這變數一旦初始化後,就不能在更改了,這樣的特性可以讓你比較清楚追蹤變數在哪邊被指定、被改到,所以如果可以的話,我們會盡可能把變數宣告為 final
  2. 我們會指定變數是否可為空,在型態後面加上問號 (?) 來表示這個變數是可以為空值,這個是在 Dart 2.12 之後導入的,如果你之前是開發 Kotlin 或者 Swift,應該對這個概念非常熟悉,這邊不多做解釋,有興趣可以前往官方文件查詢。

Constructors

宣告了數個 final 屬性後,我們必須使用 Constructor 來初始化這些變數,在 Dart 的 Constructor 預設是要使用類別名稱當作名稱,如果你有不同的建構子,那麼就可以用 類別名稱.XXX() 來宣告,我們舉個簡單例子來看不同的建構子宣告方式:

Dart 有提供語法糖,讓我們可以直接在建構子的參數指定對應的屬性,讓我們不用像以前囉唆的寫法(如下):

class Question extends StatelessWidget {
final String questionText;

Question(String questionText) {
this.questionText = questionText;
}
}

那對於我們的需求而言,我們要可以建立三種標籤樣式,所以我們提供三種不同的建構子:

這邊幾個重點:

  1. required 這關鍵字表示這個參數是必要的,每個標籤都必須指定要顯示的文字。
  2. ({…}) 大括號包起來的參數表示是用 named argument,也就是說在參數要用名稱來指定,例如:Label.filled(textColor: Colors.orange, …),如果不是 named arguement,則會變成 Label.filled(Colors.orange),這樣是用來「提高可讀性」以及指定「選擇性的參數」(可以不給)。
  3. 針對選擇性的參數我們可以指定預設值,以範例來說 textColor 就是。
  4. 建構子後面(冒號:之後的區塊)可以加入一些參數的檢查、設定預設值還有呼叫父類別的建構子。
  5. Key? key 這個有點超出這篇的內容,之後可以另外一篇,有興趣的可以自行搜尋。

建立 UI

最後是宣告我們的 UI 該怎麼呈現,我們會在 build() 方法裡實作並回傳一個 Widget,剛剛有提到「在 Flutter 世界,所有 UI 元件都是 Widgets」這句話的意思是我們的元件都是由 Widget 組合 (Composition) 而成,Widget 裡面不斷再包不同的 Widget,最後建構成我們的元件。以我們的元件來說,最裡面是一個文字標籤,外面有一個容器包著,這個容器可以是顏色填滿,或者透明只留框線:

完整 Label 元件的程式碼如下:

使用方式的範例程式如下:

結語

我們新專案花了一個月、兩個 Flutter 工程師完成(含後端 + 設計的話總共 5 位),寫完的心得就是「開發 App 比 Android 簡單太多了」,Android 太多歷史包袱,而 Flutter 的發展是在 App 或 Web 前端開發成熟許多的時期,吸取和集結各平台的精華和避免開發上的困難。

這是部落格第一篇寫 Flutter 相關的文章,我會持續找可以分享的主題或一個小型專案來分享一些 Flutter 開發經驗和學習範例,希望能精進自己的技能也能幫助大家提昇。

--

--

Engine Bai

白昌永 (大白) Software Engineer, Athlete, Learner. Focused on Mobile / Backend / AI + ML