在Flutter中使用自定義Icon

1. 前言

Flutter作為時(shí)下最流行的技術(shù)之一,憑借其出色的性能以及抹平多端的差異優(yōu)勢,早已引起大批技術(shù)愛好者的關(guān)注,甚至一些閑魚,美團(tuán),騰訊等大公司均已投入生產(chǎn)使用。雖然目前其生態(tài)還沒有完全成熟,但身靠背后的Google加持,其發(fā)展速度已經(jīng)足夠驚人,可以預(yù)見將來對(duì)Flutter開發(fā)人員的需求也會(huì)隨之增長。

無論是為了現(xiàn)在的技術(shù)嘗鮮還是將來的潮流趨勢,都9102年了,作為一個(gè)前端開發(fā)者,似乎沒有理由不去嘗試它。正是帶著這樣的心理,筆者也開始學(xué)習(xí)Flutter,同時(shí)建了一個(gè)用于練習(xí)的倉庫,后續(xù)所有代碼都會(huì)托管在上面,歡迎star,一起學(xué)習(xí)。這是我寫的Flutter系列文章:

今天要分享的內(nèi)容其實(shí)非常簡單,我們都知道Flutter內(nèi)置了一套Material Design風(fēng)格的Icon圖標(biāo),但對(duì)于一個(gè)成熟的App而言,通常情況下還是遠(yuǎn)遠(yuǎn)不夠的。為此,我們需要在項(xiàng)目中引入自定義的Icon圖標(biāo)。

本文就將以Ant Design圖標(biāo)庫為例,介紹如何在Flutter中引入自定義圖標(biāo)。

2. 準(zhǔn)備工作:字體文件

正所謂“巧婦難為無米之炊”,要想引入自定義圖標(biāo),首先我們得準(zhǔn)備好圖標(biāo)字體文件(.ttf后綴)。對(duì)于大公司而言,找視覺同學(xué)切就可以了。但如果是自己做的業(yè)余項(xiàng)目或者沒有資源的時(shí)候,我們可以上阿里巴巴矢量圖標(biāo)庫pick自己心儀的圖標(biāo)。

這里就以Ant Design官方圖標(biāo)庫為例(一共有600個(gè)圖標(biāo)),通過以下操作,我們將圖標(biāo)字體文件加入到項(xiàng)目中:

添加購物車 --> 點(diǎn)擊購物車 --> 下載代碼 --> 解壓 --> 拷貝至項(xiàng)目(可重命名)

步驟1
步驟2
步驟3

3. 聲明自定義字體

僅僅將字體文件復(fù)制到項(xiàng)目中還不夠,我們需要通過聲明的方式來告訴Flutter有新字體可用。打開項(xiàng)目根目錄下的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.

注釋就是讓我們在該段文字下方添加自定義字體的聲明,結(jié)合其注釋掉的例子和當(dāng)前的項(xiàng)目目錄,我們可以這樣配置:

項(xiàng)目工程目錄結(jié)構(gòu)
.
├── 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

注意: 配置完之后,一定要執(zhí)行flutter packages get命令以及rebuild項(xiàng)目,否則字體文件無法使用。

4. 編寫自定義的IconData

其實(shí)到目前為止,我們已經(jīng)可以使用剛剛下載的圖標(biāo)了,就像下面代碼這樣:

Icon(
  IconData(0xe77d, fontFamily: 'AntdIcons'),
  size: 20,
  color: Colors.black
)

其中fontFamily的值'AntdIcons'就是我們剛才聲明的新字體,但是代碼中的0xe77d數(shù)值是哪來的呢?再次打開之前下載解壓之后的文件夾,其中有一個(gè)demo_index.html文件,在瀏覽器中打開它我們可以看到下面的畫面:

Unicode-類型對(duì)照表

Unicode這個(gè)Tab下,我們可以看到它貼心地給出了所有圖標(biāo)的TypeUnicode碼對(duì)照關(guān)系。所以理論上來說,我們想用哪個(gè)圖標(biāo),只要copy其Unicode碼到代碼中就可以了。

不過,這種做法顯然不是很友好。首先,我們每次使用Icon之前都要從這張關(guān)系表中查找;其次,你確定下次代碼中看到這串?dāng)?shù)字是對(duì)應(yīng)什么圖標(biāo)嗎(更不用說其他人了)?所以,我們需要更優(yōu)雅的方法來管理自定義圖標(biāo)。

其實(shí)做法也簡單,我們可以創(chuàng)建一個(gè)自定義圖標(biāo)的類:

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碼的效果。不過要想用上所有的圖標(biāo),我們還得豐富AntdIcons這個(gè)類。為此,可以寫上一段小腳本,在demo_index.html瀏覽器窗口的控制臺(tái)中運(yùn)行就能得到定義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:輸出結(jié)果中可能由于圖標(biāo)作者自己命名不規(guī)范而導(dǎo)致個(gè)別的小錯(cuò)誤,手動(dòng)修改即可,完整文件可以看這里。

接下來,就是愉快玩耍的時(shí)候啦~~~

Ant Design風(fēng)格圖標(biāo)預(yù)覽

5. 總結(jié)

本文通過一個(gè)實(shí)際的Ant Design圖標(biāo)例子,詳細(xì)地介紹了如何在Flutter中引入自定義圖標(biāo),希望可以幫助到你哦~

本文所有代碼托管在這兒,也可以關(guān)注我的Blog,歡迎一起學(xué)習(xí)~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容