IconFontPreview——一款預覽IconFont的外掛
背景
使用過IconFont的應該都深有體會,每次使用IconFont的時候,由於不知道Unicode和Icon的對應關係,每次都要到對應的資料夾下找到預設生成的html檔案,開啟後才能尋找到我們需要的IconFont。而每次找檔案這個過程真的很麻煩,而且當公司IconFont的版本更新的時候,這個路徑也會相應改變,那就更痛苦了。
為了解決這個問題,我就考慮能不能做一款預覽IconFont的外掛,避免這種痛苦的尋找檔案過程,提高開發效率。
功能特性
- 支援已定義的IconFont的預覽
- 支援快取避免每次查詢
- 使用方便
原始碼地址
歡迎Star:clap:~
歡迎提issue和PR~
這裡再推薦一下我的另一個開源專案 EasyTextView ,一款高效利用IconFont的TextView,功能豐富,用過的人都說好~
jar包地址
我已經發布到Intellij的官網上了,不知道為啥搜不到
使用步驟
1.安裝完外掛後,在操作面板會生成一個草帽的Icon,點選操作面版的草帽icon(ONE PIECE)

step1
2.第一次需要設定工程下ttf字型檔案路徑和定義iconfont的string.xml路徑

step2.jpg
這一步只會在第一次才會使用,因為本地會有快取,後面的會讀取快取的目錄(根目錄下的PlugCache)
3.點選確定後或者以後在點選草帽就會在瀏覽器中開啟預覽定義的IconFont圖示了

ONE PIECE
4.後面再使用就可以直接點選操作面板的草帽Icon就會直接彈出預覽頁面了
實現原理
1.IntelliJ外掛開發
這個網上部落格很多,這裡就不專門講解了
2.XML解析
這裡本來一開始是準備直接讀取ttf檔案,然後直接生成ttf檔案中所有定義的IconFont的,但是我好像沒有找到實現方式(大家有好的實現方式可以告訴我~,或者提PR)
我們一般定義IconFont的都會在String.xml定義unicode類似於下面
<resources> <!--後退--> <string name="icon_font_606">\ue606</string> <!--評論--> <string name="icon_font_comment">\ue68f</string> <!--收藏--> <string name="icon_font_collection">\ue68e</string> <!--贊--> <string name="icon_font_like">\ue695</string> </resources>
所以這裡就需要我們遍歷XML了,這裡我選擇了SAX解析的方式,取出了定義的Key,和對應的Unicode,並儲存起來
3.Jsoup動態渲染HTML
拿到我們的資料集後,我們就需要生成我們最終的預覽頁面了,這裡直接利用IconFont固定的HTMl模版,下載下來,利用Jsoup這個HTMl解析庫,遍歷我們生成的資料集,並對應在固定位置插入HTML程式碼,最後利用File儲存到PluginCache資料夾下
這裡有幾個問題:
3.1 jar包中HTML讀取css檔案路徑問題
由於外掛最終生成的是jar檔案,所有html中的css檔案,由於路徑無法讀取,需要將css檔案拷貝到html中
3.2 快取檔案需要利用檔案流儲存,這裡涉及到外掛的資料持久化。
因為使用者設定的ttf檔案路徑和string.xml檔案路徑不能每次點選都要重新設定,哪還要這個外掛幹啥...,所以我就想將使用者設定的這兩個路徑快取起來,所以這裡就涉及到外掛的資料持久化。
網上提供的外掛持久化的兩種方式我都試了一下,發現沒法真正意義上的持久化,當你idea關閉後,這些資料都會被對應清理掉,對應於
1.使用PersistentStateComponent
2.使用PersistentStateComponent
所以最後我是用了檔案流的方式快取目錄路徑(大家如果有更好的方式可以告訴我~)
/** * 建立li */ public static final String ICON_ITEM = "<li>\n" + "<i class=\"icon iconfont\">%s</i>\n" + "<div class=\"name\">%s</div>\n" + "<div class=\"code\">%s</div>\n" + "</li>"; public void printer(String ttfPath) { InputStream html = this.getClass().getResourceAsStream(Common.HTML_PATH); try { Document doc = Jsoup.parse(html, "UTF-8", ""); if (data != null) { Elements style = doc.select("style"); style.prepend(String.format(Common.STYLE_DF, ttfPath)); Elements container = doc.getElementsByClass("icon_lists clear"); if (Common.MODE_ALL) { //全量模式,從16進位制最小值到16進位制最大值 printerAll(container); } else { //自定義模式,只輸出定義的資原始檔 printerDefine(container); } } File result = CreateFileUtil.createFile(RESULT_PATH); if (result == null) { return; } FileOutputStream outStream = new FileOutputStream(result);//檔案輸出流用於將資料寫入檔案 outStream.write(doc.toString().getBytes(StandardCharsets.UTF_8)); outStream.close(); } catch (IOException e) { e.printStackTrace(); } } private void printerDefine(Elements container) { for (Map.Entry<String, XmlIconFontModel> entry : data.getFonts().entrySet()) { String code = entry.getValue().getFontValue(); if (code.startsWith(Common.ICON_START)) { String value = "" + code.substring(3) + ";"; container.append(String.format(Common.ICON_ITEM, value, entry.getValue().getFontKey(), code)); } else if (code.startsWith(Common.ICON_START_SUB)) { container.append(String.format(Common.ICON_ITEM, code, entry.getValue().getFontKey(), code)); } } }
4.利用exec執行命令,開啟生成的html檔案
/** * 執行展示 */ try { if (OSinfo.isWindows()) { Runtime.getRuntime().exec("cmd.exe /c start " + RESULT_PATH); } else { Runtime.getRuntime().exec("open " + RESULT_PATH); } } catch (Exception e) { e.printStackTrace(); }