認識UI框架時,若流於UI元件的個別認識與組合,易迷失於成千上萬的UI元件,不知如何變化;掌握API架構,如繼承與物件行為互動間的關係,甚至是UI設計原則,才是根本之道。

UI框架的起手式

對於手機、平板的應用程式,我一向很絕緣,總是提不起興趣,一方面是平臺不同,方案就相異,另一方面應該與接觸的文件或書籍有關,App天生就是圖形操作介面,文件或書籍一開始必然談到UI元件的使用,我往往看個幾章就會開始厭煩「喔!UI元件好多,組合來組合去的,記也記不住,以後用到再說吧!」後來沒用到,也不再去理它們了。

最近Flutter這名詞,時不時會跑到我社交媒體的動態訊息中,心想「好吧!至少它號稱可以跨平臺,看看能不能燃燒起我學習App的熱誠!」結果看了幾篇文件,又開始昏昏欲睡,「以後再說」的念頭就又出現了,然而,接下來想到的是:「為什麼這類UI在談時老會讓我有這種念頭?」。

首先,Android Studio內建的Flutter範例專案,就HelloWorld的作用來說,顯然一次給太多訊息了,就算拿掉註解也還有60行左右,對我來說,寫出一個越簡單越好的HelloWorld程式,才代表對一個框架或平臺有了初步認識,我試著摸索,寫了不到10行的HelloWorld程式,才終於有了起步的感覺!

在摸索簡單HelloWorld的過程中,總覺得一直看到React的感覺,確實,在官方文件〈Introduction to widgets〉第一句就談到,Flutter中的Widget就是受到React的啟發。

這就讓我想到React Native,也是號稱可跨平臺的設計,那麼兩者的差異呢?決定性的不同在於,ReactNative是透過橋接的方式,操作各平臺的原生UI元件,Flutter是描述好畫面該如何呈現,然後在各平臺原生的Canvas元件上畫出來;這代表著Flutter能描述的元件,在各平臺的螢幕就都可以展現,不用受限於原生UI元件提供了哪些東西,

萬物皆Widget

雖說最後都是用具體的UI元件來組裝出畫面,然而,面對UI框架時,若只知道具體元件,就容易迷失於一個又一個範例;寫出最簡單的HelloWorld是個起點,也是為了初步認識這些元件的API架構,像是繼承與物件行為互動間的關係。

Fultter的執行起點是runApp方法,接受Widget實例,在Flutter中,與使用者介面相關的資訊,幾乎都跟Widget有關,文字、圖片、Icon等使用者介面元件,都使用Widget來描述,看不到的東西也是Widget,例如布局(layout)相關的元件。

乍看Widget是組成畫面的元素,其實它是描述組態與狀態的物件,類似React的Component;在Flutter中,組成畫面的元素會用Element實例表示,某些程度上,Element可以比擬為HTML DOM,Element是根據Widget的組態與狀態而建立,具體而言,是透過Widget的createElemnet方法建立。

我們可以將Widget想像成對應React虛擬DOM的類似品,被指定給runApp的Widget,會作為Widget樹的根,Widget的組態、狀態等資訊會用來建立Element,這些Element用來管理底層的渲染樹(render tree),基本上可以認知為Widget樹有變動,畫面就會變動。

當然實際這麼做的話,畫面重建的負擔很重,因此Flutter將Widget分為子類StatelessWidget、StatefulWidget,前者用來組裝畫面上不變動的元件,相對應的Element也就不用變動,藉由重用來減輕畫面重建時的負擔;若是畫面上會變動的元件,才繼承StatefulWidget,在其關聯的State物件被改變時,透過setState方法通知,重新建立新的Widget,取代畫面上會變動的元件。

在Flutter中進行布局的相關元件,也是Widget,認識布局相關Widget的方向有兩個:一個方式是從其可容納單一子元素或多個子元素來認識,官方文件〈Layout widgets〉就是以此分類,我個人則是偏好從繼承架構與API原始碼中來認識,可以同時知道布局元件間的關係,以及生命週期關係等原理。

我們可先認識Widget子類RenderObjectWidget,因為其子類別都與布局有關,例如置中對齊、行排列、列排列等,像是入門文件常見的Center、Row、Column,都是RenderObjectWidget的子類別。

Material Design

我們在設計現代App時,並不只是認識元件組裝,往往還必須遵循一些設計準則,例如許多Flutter文件的起手式,都會使用MaterialApp,它是個用來實作Material Design風格的支援類別。

Material Design是一套設計指南,目的是為了讓介面設計營造最佳使用者經驗,若想詳細瞭解Material Design,當然是詳閱官方文件〈Material Design〉,不想看英文,也有正體中文版,只不過,對於開發者來說,這份指南也太詳細了。

開發者可以從Android使用者經驗總監Matias Durate,在2014年Google發布Material Design的發言,來認識Material Design,他說:「We imagined…what if pixels didn’t just have color, but also depth? What if there was a material that could change its texture? This lead us to something we call ‘material design…」。

想像一下,若像素不只有顏色,還能有深度等資訊,就像材質(material)可以更換貼圖(texture)的話,就會產生Material Design這樣的設計準則。

簡單來說,對於平面螢幕裝置的介面設計(手機App、Web網頁,甚至是桌面應用程式),Material Design主張不應局限於實體元件的模擬(例如在手機螢幕中模擬實體世界的立體按鈕),畢竟電子螢幕中的數位元素,不存在於實體世界,應該要去重新定義數位元素本身應有的樣貌、彈性與屬性。

就開發者這方面,主要可以先知道準則的出發點是「使用者操作的是平面」這個事實,重要的就是如何在平面展現資訊,這方面可借鏡紙張的概念,例如大區塊化、高對比、標題與內容的區隔等,簡單來說,可試著從各式印刷品中構思設計靈感。

接著是「資訊有層級關係」,在印刷品上,層次關係主要來自於列印段落、縮排、提示文字、引言等,或來自於頁與頁之間的轉換;然而,電子螢幕除了X、Y座標等可作為層次之外,還可以有顏色、深度、陰影等方式來塑造層次關係。

再來是「善用材質(material)特性」,將像素視為材質,就可以有為材質更換貼圖的設計概念,例如,就按鈕概念來說,沒必要單純模擬實體世界的按鈕,數位世界中的按鈕能做到什麼,適當的時候就讓它做到什麼,因此,按鈕可以是浮動的、無邊框的,甚至與使用者進行對話。

不只是具體元件的組裝

與傳統桌面UI不同,手機、平板這類數位產品,在應用程式開發時,設計風格會是必要的考量,雖說Material Design是UX/UI設計師的職責,不過,在現實生活中,有時開發者也必須處理這件事。

然而,不僅是為了將來「校長兼撞鐘」而準備,在認識了這類設計原則之後,也有助於掌握UI元件可設定的相關特性,一開始積極認識API架構,甚至是認識框架發想的起點,也是為了能簡馭繁,駕馭諸多UI元件,對於UI框架本身在學習上,也可以產生更多探索的樂趣。

作者簡介


Advertisement

更多 iThome相關內容