在Flutter中使用自定義Icon

SmallStoneSK發表於2019-07-14

1. 前言

Flutter作為時下最流行的技術之一,憑藉其出色的效能以及抹平多端的差異優勢,早已引起大批技術愛好者的關注,甚至一些閒魚美團騰訊等大公司均已投入生產使用。雖然目前其生態還沒有完全成熟,但身靠背後的Google加持,其發展速度已經足夠驚人,可以預見將來對Flutter開發人員的需求也會隨之增長。

無論是為了技術嚐鮮還是以後可能的工作機會,都9102年了,作為一個前端開發者,似乎沒有理由不去嘗試它。正是帶著這樣的心理,筆者也開始學習Flutter,同時建了一個用於練習的倉庫,後續所有程式碼都會託管在上面,歡迎star,一起學習。

今天要分享的內容其實非常簡單,我們都知道Flutter內建了一套Material Design風格的Icon圖示,但對於一個成熟的App而言,通常情況下還是遠遠不夠的。為此,我們需要在專案中引入自定義的Icon圖示

本文就將以Ant Design圖示庫為例,介紹如何在Flutter中引入自定義圖示。

2. 準備工作:字型檔案

正所謂“巧婦難為無米之炊”,要想引入自定義圖示,首先我們得準備好圖示字型檔案(.ttf字尾)。對於大公司而言,找視覺同學切就可以了。但如果是自己做的業餘專案或者沒有資源的時候,我們可以上阿里巴巴向量圖示庫pick自己心儀的圖示。

這裡就以Ant Design官方圖示庫為例(一共有600個圖示),通過以下操作,我們將圖示字型檔案加入到專案中:

新增購物車 --> 點選購物車 --> 下載程式碼 --> 解壓 --> 拷貝至專案(可重新命名)

步驟1

步驟2

步驟3

3. 宣告自定義字型

僅僅將字型檔案複製到專案中還不夠,我們需要通過宣告的方式來告訴Flutter有新字型可用。開啟專案根目錄下的pubspec.yaml檔案,找到fonts這一段:

To add custom fonts to your application, add a fonts section here, in this "flutter" section. Each entry in this list should have a "family" key with the font family name, and a "fonts" key with a list giving the asset and other descriptors for the font.

註釋就是讓我們在該段文字下方新增自定義字型的宣告,結合其註釋掉的例子和當前的專案目錄,我們可以這樣配置:

專案工程目錄結構
.
├── README.md
├── android
│   └── app
├── assets
│   └── fonts
│       └── AntdIcons.ttf
├── flutter_training_app.iml
├── ios
│   └── Flutter
├── lib
│   └── main.dart
├── pubspec.lock
└── pubspec.yaml

字型宣告
fonts:
  - family: AntdIcons
    fonts:
      - asset: assets/fonts/AntdIcons.ttf
複製程式碼

注意: 配置完之後,一定要執行flutter packages get命令以及rebuild專案,否則字型檔案無法使用。

4. 編寫自定義的IconData

其實到目前為止,我們已經可以使用剛剛下載的圖示了,就像下面程式碼這樣:

Icon(
  IconData(0xe77d, fontFamily: 'AntdIcons'),
  size: 20,
  color: Colors.black
)
複製程式碼

其中fontFamily的值'AntdIcons'就是我們剛才宣告的新字型,但是程式碼中的0xe77d數值是哪來的呢?再次開啟之前下載解壓之後的資料夾,其中有一個demo_index.html檔案,在瀏覽器中開啟它我們可以看到下面的畫面:

Unicode圖示型別對照表

Unicode這個Tab下,我們可以看到它貼心地給出了所有圖示的TypeUnicode碼對照關係。所以理論上來說,我們想用哪個圖示,只要copy其Unicode碼到程式碼中就可以了。

不過,這種做法顯然不是很友好。首先,我們每次使用Icon之前都要從這張關係表中查詢;其次,你確定下次程式碼中看到這串數字是對應什麼圖示嗎?所以,我們需要更優雅的方法來管理自定義圖示。

其實做法也簡單,我們可以建立一個自定義圖示的類:

class AntdIcons {
  static const IconData checkCircle = IconData(0xe77d, fontFamily: 'AntdIcons');
  static const IconData CI = IconData(0xe77e, fontFamily: 'AntdIcons');
  static const IconData Dollar = IconData(0xe77f, fontFamily: 'AntdIcons');
  ...
}
複製程式碼

然後使用方法就變成了:

Icon(
  AntdIcons.checkCircle,
  size: 20,
  color: Colors.black
)
複製程式碼

以上程式碼完全等同於前面直接使用Unicode碼的效果。不過要想用上所有的圖示,我們還得豐富AntdIcons這個類。為此,可以寫上一段小指令碼,在demo_index.html瀏覽器視窗的控制檯中執行就能得到定義IconData的程式碼:

function camelCase(str) {
  return str.replace(/[ -]+(\w)/g, (match, char) => char.toUpperCase());
}

function makeCode({name, code}) {
  return `static const IconData ${camelCase(name)} = IconData(0${code.substr(2, 5)}, fontFamily: 'antd-icons');\n`;
}

Array
  .from(document.querySelectorAll('.unicode .dib'))
  .map(element => {
    return {
      name: element.querySelector('.name').innerText,
      code: element.querySelector('.code-name').innerText
    };
  })
  .map(makeCode)
  .join('\n');
複製程式碼

PS:輸出結果中可能由於圖示作者自己命名不規範而導致個別的小錯誤,手動修改即可,完整檔案可以看這裡

接下來,就是愉快玩耍的時候啦~~~

在Flutter中使用自定義Icon

5. 總結

本文通過一個實際的Ant Design圖示例子,詳細地介紹瞭如何在Flutter中引入自定義圖示,希望可以幫助到你哦~

本文所有程式碼託管在這兒,也可以關注我的Blog,歡迎一起學習~

相關文章