屏幕適配的頂級淫技:使用 TextView 來顯示圖片

今天咱們來介紹一種用 TextView 代替並顯示圖片,以達到App優化及圖標自適應的效果。而圖片大小等的設置依舊使用 TextView 的各原生方法。 html

這裏先放上本文的GitHub 連接:github.com/OCNYang/Fon… android

首先,咱們先來看一下效果: git

這些真的只是TextView文本
這些真的只是TextView文本

若是你看到上面這張圖片,第一反映你可能認爲都是用ImageView去顯示的,那你就錯了,這些全都是用TextView實現的(固然更不多是給 TextView 設置了背景圖)。 github

平時咱們在開發中,圖片可謂是到處可見且必不可少的一部分,爲了想盡辦法讓圖片達到適配的效果咱們可能須要:
根據不一樣分辨率來提供多套圖,暫且不說這種方式是否麻煩,正常狀況下咱們切的三套或更多套圖有時候總在有些機型上的效果不盡人意。
可能這時候你想到了用 .9圖片,這時候且不說大家家 UI 妹子會不會單獨的爲咱們 Android 端提供 .9圖片 (姑且相信大家家UI會製做.9),可是 .9圖片 是有必定的侷限性的,它只能是圖片部分區域拉伸。 web

這篇文章也並非去介紹如何去作圖片的適配,而是介紹一種利用字體庫的方式,咱們用 TextView 的形式去顯示圖片,並且咱們還能夠正常的使用 android:textSize 屬性來隨意設置圖片的大小! bash

其實這裏經過 TextView 來顯示圖片的方式,我更願意更準確的說成是經過 TextView 來顯示圖標,由於這裏的圖片不是真正意義上的大圖而是至關於能夠隨意拉伸的矢量圖。固然,若是你願意你也能夠用這種方式來顯示圖片。 網絡

囉嗦這麼多,你的大刀是否是早就飢渴難耐了?其實這種方式很容易就能實現,只是經過給 TextView 設置一種字體,不要着急,立刻開始。 app

爲TextView設置字體

你們都知道,在 android 中,咱們若是要更換字體,除了要引入咱們須要的字體庫外,還須要給咱們的 TextView 去手動設置使用的字體,如何去設置呢?其實很簡單。ide

textView.setTypeface(Typeface tf);  複製代碼

儘管就這麼一行代碼,可是,在咱們項目中確定會存在大量的TextView,難道咱們要一個個的去動手設置嗎?想一想這也是一件很頭疼的事,下面就介紹一種方便的方法,一行代碼解決字體設置的問題。 svg

方法一:工具類 & 遞歸遍歷

在看代碼以前,先來看看思路,其實思路很簡單,咱們提供一個根佈局,寫一個方法去遞歸遍歷整個根佈局,若是發現是textView,則設置字體。思路很簡單,相信代碼也很簡單,就是一個遞歸方法。

public class FontHelper {
    public static final String DEF_FONT = "fonts/ocnyangfont.ttf";

    public static final void injectFont(View rootView) {
        injectFont(rootView, Typeface.createFromAsset(rootView.getContext().getAssets(),
                DEF_FONT));
    }

    private static void injectFont(View rootView, Typeface typeface) {
        if (rootView instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) rootView;
            int childViewCount = viewGroup.getChildCount();
            for (int i = 0; i < childViewCount; i++) {
                injectFont(viewGroup.getChildAt(i), typeface);
            }
        } else if (rootView instanceof TextView) {
            ((TextView) rootView).setTypeface(typeface);
        }
    }
} 複製代碼

定義了一個工具類,這個類提供兩個靜態方法,可是核心都是

public static final void injectFont(View rootView, Typeface tf)複製代碼

這個方法中,首先咱們去判斷咱們給的rootView是否是ViewGroup,若是是ViewGroup,則遍歷他的全部子view,而後遞歸去調用這個方法,直到所有完成,若是發現某個view是TextView,則咱們調用setTypeface方法來設置字體。
ok,從這個工具類中咱們還能夠看到,咱們的字體是放在assets/fonts目錄下的。

最後是在activity中使用字體庫,正式利用了上面的工具類,因此咱們的代碼將會很簡單。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    FontHelper.injectFont(findViewById(android.R.id.content));
}複製代碼

僅僅一行代碼,FontHelper.injectFont(findViewById(android.R.id.content));
咱們就完成了給全部TextView設置字體的工做。

方法二:LayoutInflate

如今對 LayoutInflateFactory 的用法還不太熟悉的,能夠先去看一下鴻洋的這篇博文:探究 LayoutInflate setFactory

咱們編寫一個自定義的LayoutInflaterFactory:

public class IconFontLayoutFactory implements LayoutInflaterFactory {

    private static Typeface sTypeface;
    private AppCompatDelegate mAppCompatDelegate;

    public IconFontLayoutFactory(Context context,
                                 AppCompatDelegate appCompatDelegate) {
        if (sTypeface == null) {
            sTypeface = Typeface.createFromAsset(context.getAssets(),
                    "fonts/ocnyangfont.ttf");
        }
        mAppCompatDelegate = appCompatDelegate;
    }

    @Override
    public View onCreateView(View parent, String name, Context context,
                             AttributeSet attrs) {
        View view = mAppCompatDelegate.createView(parent, name, context, attrs);
        if (view instanceof TextView) {
            ((TextView) view).setTypeface(sTypeface);
        }
        return view;
    }
}複製代碼

字體文件咱們仍是放在 assets/fonts 目錄下。

而後你能夠在你的BaseActivity的onCreate中,調用以下代碼:

@Override
protected void onCreate(Bundle savedInstanceState) {

        LayoutInflaterCompat.setFactory(getLayoutInflater(),
                new IconFontLayoutFactory(this,getDelegate()));

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}複製代碼

注意必定要在super.onCreate前調用便可。

該方式能夠在TextView及其子類對象建立完成時,就能夠爲其調用setTypeFace,很是的高效。
而對於字體庫的加載,若是有須要,你甚至能夠採用懶加載的方式,在SplashActivity中對其初始化。

這裏提供是兩種全局設置的方式。
有時候咱們只是須要給部分 TextView 設置,這時候你們能夠選擇手動單獨給特定的 TextView 設置,也能夠經過自定義 View 的方案來實現(在構造方法中去設置 TypeFace,我我的也比較提倡這種方式,使用上相對靈活,也很簡單這裏就不囉嗦了,詳細代碼能夠到這裏下載 本文源碼 內查看)。

那上面這些只是如何設置字體的方法,可能你也早就知道了,字體是字體,也不是圖片呀,大兄弟莫慌,下面就給你如何介紹一種酷炫的字體庫和製做本身獨特的圖片字體庫的方法。

fontawesome 字體庫的使用

在開始使用以前,咱們咱們須要到
github.com/FortAwesome…
下載這個字體庫(不想麻煩,本文 源代碼 也包含有)。下載下來之後,你會看到有不少目錄和文件,不要緊,咱們只須要一個文件-fontawesome-webfont.ttf,這個文件位於/fonts/目錄下。將這個ttf文件copy到你項目的assets目錄下,按照慣例或者說是共識,咱們多是將它放到assets/fonts這個目錄下(注意,沒有這個目錄的話,建立它!)。

ok, 準備工做都作好了,那咱們就開始使用它吧,看個人xml佈局文件:

<LinearLayout
    //...
    >

    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_margin="10dp"
        android:textSize="58sp"
        android:textColor="#ff995533"
        android:layout_height="wrap_content"
        android:text=""/>

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_margin="10dp"
        android:textSize="118sp"
        android:textColor="#ff9ff533"
        android:layout_height="wrap_content"
        android:text=""/>

    //...

</LinearLayout>複製代碼

看到這個佈局文件,咱們看到和平時沒什麼區別,給出了textSize或者textColor屬性,不用想這些確定去控制了咱們須要顯示的圖片的大小和顏色!

細心的你會發現這些 TextView 文本好奇怪。其實這些文本對應的就是相對於的圖片。但是,如今咱們又遇到了一個問題,咱們怎麼知道哪寫文本表明了什麼圖片呢?下面給出一個網址,經過這個網址,你們能夠看到實體文本和他對應的圖片的一個對照表。

fortawesome.github.io/Font-Awesom…

本文 源碼 內咱們提供了一個 string.xml 文件的圖片字符對照表,能夠直接在項目中使用。
你也能夠在根據本身的須要在上面 string.xml 文件裏 Ctrl + F 檢索出對應的編碼放到本身的字符串文件裏或直接使用。

哦,對了,不知道你們有沒有發現,這裏咱們無心中解決了一個圖片大小的問題,由於咱們能夠任意改變一個文本的大小,因此,就不須要提供多套圖去適配不一樣的屏幕了。

這是你可能仍是有疑問,Font-Awesome 庫 內提供的圖標雖然很全很美觀,可是不必定能知足咱們全部的須要啊!那如今就教你們如何製做屬於本身的字體庫。

製做屬於本身的圖片字體庫

在本身動手製做圖片字體庫以前,固然要先查找一些本身喜歡的漂亮的圖標了,下面開啓乾貨福利模式。

圖標乾貨

對於使用,最主要就是找到一些靠譜的素材站點了

www.iconfont.cn/
icomoon.io/app/#/selec…
github.com/mikepenz/An…

第一個站點是阿里提供的圖標庫,基本上能夠搜索到須要的任何圖標,很是方便,也支持顏色和大小的設置,足夠知足咱們的需求:

阿里 iconfont 圖標庫
阿里 iconfont 圖標庫

自定義圖標

不管上面這些網站提供的圖標是多麼的全,可能都沒法知足貪心的你或者大家家追求完美(矯情)到極致的UI,那麼若是App內的圖標部分是本身製做的,再混雜着網絡上已有的圖標能打包到一個字體庫麼?
答案固然是確定的,咱們原本就是要製做屬於本身的字體庫嘛!好比你就能夠依賴 iconfont.com 這個網站,自行上傳svg圖標,而後就能夠自由選擇了。

關於 iconfont 網站的用法能夠參考官方手冊(也能夠跳過,直接跟着我學習怎麼生成本身的字體庫):
www.iconfont.cn/help/platfo…

按需生成本身的圖標字體庫

咱們以 iconfont 庫爲例,教你們生成本身圖片字體庫的整個流程(下面全部步驟,你們都無需註冊帳號,就能夠直接使用)。

首先在 iconfont 網站上選擇本身要生成到字體庫的圖標,能夠選擇網站字體庫中選擇,也能夠在個人圖標庫中選擇本身上傳的圖標。把這些圖標添加到庫(即添加到購物車):

選擇喜歡的圖標
選擇喜歡的圖標

添加到購物車
添加到購物車

當你想要生成的字體庫的圖標選擇完成後,在網站右上角點擊打開庫(購物車),在庫裏能夠看到本身選擇的全部圖標,肯定後點擊下載代碼:

打開庫,下載代碼會獲得一個壓縮包
打開庫,下載代碼會獲得一個壓縮包

解壓縮後,能夠看到生成的庫
解壓縮後,能夠看到生成的庫

在解壓後的文件夾中,咱們看到許多文件。其中以 .ttf 結尾的文件就是咱們生成的本身的字體庫,而 3 個 .html 文件對應的是不一樣平臺使用時對應的編碼。而咱們在 Android 開發中要使用的編碼是 demo_unicode.html 文件裏對應的 &#xxxxx; 形式的編碼。

細心的你必定會發現,生成的字體庫裏雖然包含了不少圖標,卻只有小小的幾 KB 的大小,更難能難得的是不管設置多大的尺寸它依舊可以保存同樣的清晰度,固然,你也能夠把該方案當作apk瘦身的可選手段之一。

本文Demo源代碼下載地址:github.com/OCNYang/Fon…

參考:
亓斌 - FontAwesome-用TextView顯示圖片
鴻洋 - Android IconFont全攻略
How to Use FontAwesome in an Android App

相關文章
相關標籤/搜索