Flutter 經(jīng)典控件學(xué)習(xí)(文本斩启、圖片、按鈕)

前言

在此之前醉锅,花費了很長時間學(xué)習(xí)了視圖數(shù)據(jù)流轉(zhuǎn)機制兔簇、底層渲染方案、視圖更新策略等知識硬耍,都是構(gòu)成一個 UI 框架的根本垄琐,看似枯燥,卻往往具有最長久的生命力经柴。新框架每年層出不窮狸窘,可是扒下那層炫酷的“外衣”,里面其實還是那些最基礎(chǔ)的知識和原理坯认。

因此翻擒,只有把這些最基礎(chǔ)的知識弄明白,修煉好內(nèi)功牛哺,才能觸類旁通陋气,由點及面形成自己的知識體系,也能夠在框架之上思考應(yīng)用層構(gòu)建視圖實現(xiàn)的合理性引润。

在對視圖的基礎(chǔ)知識有了整體印象后巩趁,再來學(xué)習(xí) Flutter 視圖系統(tǒng)提供所提供的 UI 控件,就會事半功倍淳附。作為一個 UI 框架晶渠,與 Android凰荚、iOS 類似的,F(xiàn)lutter 自然也提供了很多 UI 控件褒脯。而文本便瑟、圖片和按鈕則是這些不同的 UI 框架中構(gòu)建視圖都要用到的三個最基礎(chǔ)的控件。

(一)文本控件

在 Flutter 中番川,文本展示是通過 Text 控件實現(xiàn)的到涂。

Text 支持兩種類型的文本展示,一個是默認(rèn)的展示單一樣式的文本 Text颁督,另一個是支持多種混合樣式的富文本 Text.rich践啄。

(1)單一樣式的文本 Text

單一樣式文本 Text 的初始化,是要傳入需要展示的字符串沉御。而這個字符串的具體展示效果屿讽,受構(gòu)造函數(shù)中的其他參數(shù)控制。這些參數(shù)大致可以分為兩類:

  • 控制整體文本布局的參數(shù)吠裆,如文本對齊方式 textAlign伐谈、文本排版方向 textDirection,文本顯示最大行數(shù) maxLines试疙、文本截斷規(guī)則 overflow 等等诵棵,這些都是構(gòu)造函數(shù)中的參數(shù);
  • 控制文本展示樣式的參數(shù)祝旷,如字體名稱 fontFamily履澳、字體大小 fontSize、文本顏色 color怀跛、文本陰影 shadows 等等距贷,這些參數(shù)被統(tǒng)一封裝到了構(gòu)造函數(shù)中的參數(shù) style 中。
Text(
    'Hello World',
    textAlign: TextAlign.center, // 顯示居中
    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.red) // 20號紅色粗體
)
單一樣式文本 Text
(2)多種混合展示樣式

混合展示樣式與單一樣式的關(guān)鍵區(qū)別在于分片吻谋,即如何把一段字符串分為幾個片段來管理忠蝗,給每個片段單獨設(shè)置樣式。在 Flutter 中使用 TextSpan滨溉。

TextSpan 定義了一個字符串片段該如何控制其展示樣式什湘,而將這些有著獨立展示樣式的字符串組裝在一起长赞,則可以支持混合樣式的富文本展示晦攒。

TextStyle blackStyle = TextStyle(fontWeight: FontWeight.normal, fontSize: 20, color: Colors.black); // 黑色樣式
TextStyle redStyle = TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.red); // 紅色樣式

Text.rich(
            TextSpan(children: <TextSpan>[
              TextSpan(text: 'Hello', style: blackStyle),
              TextSpan(text: 'World', style: redStyle)
            ]),
            textAlign: TextAlign.center,
          ),
多種混合樣式富文本 Text.rich

(二)圖片

使用 Image,可以讓我們向用戶展示一張圖片得哆。圖片的顯示方式有很多脯颜,比如資源圖片、網(wǎng)絡(luò)圖片贩据、文件圖片等栋操,圖片格式也各不相同闸餐,因此在 Flutter 中也有多種方式,用來加載不同形式矾芙、支持不同格式的圖片:

  • 加載本地資源圖片舍沙,如 Image.asset(‘images/logo.png’);
  • 加載本地(File 文件)圖片剔宪,如 Image.file(new File(’/storage/xxx/xxx/test.jpg’))拂铡;
  • 加載網(wǎng)絡(luò)圖片,如 Image.network(<code>'http://xxx/xxx/test.gif'</code>) 葱绒。

除了可以根據(jù)圖片的顯示方式設(shè)置不同的圖片源之外感帅,圖片的構(gòu)造方法還提供了填充模式 fit、拉伸模式 centerSlice地淀、重復(fù)模式 repeat 等屬性失球,可以針對圖片與目標(biāo)區(qū)域的寬高比差異制定排版模式。

在加載網(wǎng)絡(luò)圖片的時候帮毁,為了提升用戶的等待體驗实苞,我們往往會加入占位圖、加載動畫等元素作箍,這時候我需要用到 FadeInImage 控件硬梁。

FadeInImage 控件提供了圖片占位的功能,并且支持在圖片加載完成時淡入淡出的視覺效果胞得。此外荧止,由于 Image 支持 gif 格式,我們甚至還可以將一些炫酷的加載動畫作為占位圖阶剑。

 FadeInImage.assetNetwork(
          placeholder: 'images/loading.gif',
          image: '[https://avatars2.githubusercontent.com/u/30656290?s=400&u=09c8f2272dc7055321ef0a5a5350ddf1c6f3a293&v=4](https://avatars2.githubusercontent.com/u/30656290?s=400&u=09c8f2272dc7055321ef0a5a5350ddf1c6f3a293&v=4)
',
          fit: BoxFit.cover,
          width: 200,
          height: 200,
        )
FadeInImage 占位圖

Image 控件需要根據(jù)圖片資源異步加載的情況跃巡,決定自身的顯示效果,因此是一個 StatefulWidget牧愁。圖片加載過程由 ImageProvider 觸發(fā)素邪,而 ImageProvider 表示異步獲取圖片數(shù)據(jù)的操作,可以從資源猪半、文件和網(wǎng)絡(luò)等不同的渠道獲取圖片兔朦。

首先,ImageProvider 根據(jù) _ImageState 中傳遞的圖片配置生成對應(yīng)的圖片緩存 key磨确;然后沽甥,去 ImageCache 中查找是否有對應(yīng)的圖片緩存,如果有乏奥,則通知 _ImageState 刷新 UI摆舟;如果沒有,則啟動 ImageStream 開始異步加載,加載完畢后恨诱,更新緩存媳瞪;最后,通知 _ImageState 刷新 UI照宝。

圖片加載流程

值得注意的是蛇受,ImageCache 使用 LRU(Least Recently Ised,最近最少使用)算法進行緩存更新策略厕鹃,并且默認(rèn)最多儲存 1000 張圖片龙巨,最大緩存限制為 100 MB,當(dāng)限定的空間已存滿數(shù)據(jù)時熊响,把最久沒有被訪問到的圖片清除旨别。圖片緩存只會在運行期間生效,也就是只緩存在內(nèi)存中汗茄。如果想要支持緩存到文件系統(tǒng)秸弛,可以使用 Flutter 第三方的 CachedNetworkImage 控件。

CachedNetworkImage 的使用方法與 Image 類似洪碳,除了支持圖片緩存外递览,還提供了比 FadeImage 更強大的加載過程占位與加載錯誤占位,可以支持比用圖片占位更靈活的自動以控件占位瞳腌。


(三)按鈕

通過按鈕绞铃,響應(yīng)用戶的交互事件。Flutter 提供了三個基本的按鈕控件嫂侍,F(xiàn)latButton 儿捧、RaisedButton 和 FloatingActionButton。

  • FlatButton:扁平化的按鈕挑宠,默認(rèn)透明背景菲盾,被點擊后會呈現(xiàn)灰色背景。
  • RaisedButton:凸起的按鈕各淀,默認(rèn)帶有灰色背景懒鉴,被點擊后灰色背景會加深。
  • FloatingActionButton:一個圓形的按鈕碎浇,一般出現(xiàn)在屏幕內(nèi)容的前面临谱,用來處理界面中最常用、最基礎(chǔ)的用戶動作奴璃。在 Flutter 官方示例模板中悉默,計數(shù)器的 “+” 懸浮按鈕就是一個 FloatingActionButton。

示例代碼溺健,縱列的布局中麦牺,分別排列三個樣式按鈕:

body: Column(
        children: <Widget>[
          FlatButton(
            onPressed: () => print('FlatButton pressed'),
            child: Text('Btn1'),
          ),
          RaisedButton(
            onPressed: () => print('RaisedButton pressed'),
            child: Text('Btn2'),
          ),
          FloatingActionButton(
            onPressed: () => print('FloatingActionButton pressed'),
            child: Text('Btn3'),
          )
        ],
      ),
按鈕效果

既然是按鈕,因此除了控制基本樣式之外鞭缭,還需要響應(yīng)用戶點擊行為剖膳。這就對應(yīng)著按鈕控件中的兩個最重要的參數(shù)了:

  • onPressed 參數(shù)用于設(shè)置點擊回調(diào),告訴 Flutter 在按鈕被點擊時通知我們岭辣。如果 onPressed 參數(shù)為空吱晒,則按鈕會處于禁用狀態(tài),不響應(yīng)用戶點擊沦童。
  • child 參數(shù)用于設(shè)置按鈕的內(nèi)容仑濒,告訴 Flutter 控件應(yīng)該長成什么樣,也就是控制著按鈕控件的基本樣式偷遗。child 可以接收任意的 Widget墩瞳,比如我們在上面的例子中傳入的 Text,除此之外我們還可以傳入 Image 等控件氏豌。

雖然我們可以通過 child 參數(shù)來控制按鈕控件的基本樣式喉酌,但是系統(tǒng)默認(rèn)的樣式還是太單調(diào)了。因此通常情況下泵喘,我們還是會進行控件樣式定制泪电。

與 Text 控件類似,按鈕控件也提供了豐富的樣式定制功能纪铺,比如背景顏色 color相速、按鈕形狀 shape、主題顏色 colorBrightness鲜锚,等等突诬。

示例代碼:

body: FlatButton(
    // 設(shè)置背景色為粉色
    color: Colors.pink,
    // 設(shè)置斜角矩形邊框
    shape: BeveledRectangleBorder(
        borderRadius: BorderRadius.circular(20.0)),
    // 確保文字按鈕為深色
    colorBrightness: Brightness.light,
    onPressed: () => print('FlatButton pressed'),
    child: Row(
      children: <Widget>[Icon(Icons.add), Text("Add")],
    )
)
按鈕控件定制外觀

可以看到,我們將一個加號 Icon 與文本組合芜繁,定義了按鈕的基本外觀攒霹;隨后通過 shape 來指定其外形為一個斜角矩形邊框,并將按鈕的背景色設(shè)置為黃色浆洗。

因為按鈕背景顏色是淺色的催束,為避免按鈕文字看不清楚,我們通過設(shè)置按鈕主題 colorBrightness 為 Brightness.light伏社,保證按鈕文字顏色為深色抠刺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市摘昌,隨后出現(xiàn)的幾起案子速妖,更是在濱河造成了極大的恐慌,老刑警劉巖聪黎,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罕容,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機锦秒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門露泊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人旅择,你說我怎么就攤上這事惭笑。” “怎么了生真?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵沉噩,是天一觀的道長。 經(jīng)常有香客問我柱蟀,道長川蒙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任长已,我火速辦了婚禮派歌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痰哨。我一直安慰自己胶果,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布斤斧。 她就那樣靜靜地躺著早抠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撬讽。 梳的紋絲不亂的頭發(fā)上蕊连,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音游昼,去河邊找鬼甘苍。 笑死,一個胖子當(dāng)著我的面吹牛烘豌,可吹牛的內(nèi)容都是我干的载庭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼廊佩,長吁一口氣:“原來是場噩夢啊……” “哼囚聚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起标锄,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤顽铸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后料皇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谓松,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡星压,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鬼譬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娜膘。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拧簸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情男窟,我是刑警寧澤盆赤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站歉眷,受9級特大地震影響牺六,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜汗捡,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一淑际、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扇住,春花似錦春缕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至女阀,卻和暖如春宅荤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浸策。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工冯键, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庸汗。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓惫确,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蚯舱。 傳聞我的和親對象是個殘疾皇子雕薪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355