Android Text View with Custom Font

Hujiawei Bujidao


     

Android Text View with Custom Font


本文以自定义TextView为例简单实践下如何自定义View,它能够根据设置的xml属性采用不同的字体显示文字

效果如下图所示:

images

如果你是使用Android Studio的话,那么Custom View操作很简单,只需要new -> UI Component -> Custom View就好了,IDE会自动帮你生成一些有用的代码,然后根据实际需要修改就行了,这里我还是一个个文件创建吧。

你可以从这个网站下载免费的字体文件(需要是ttf格式的)。

(1)新建文件res/values/attrs_font_textview.xml,其中定义一下我们的TextView的属性fontType,用来指明使用的字体。

<resources>
    <declare-styleable name="FontTextView">
        <attr name="fontType" format="string"/>
    </declare-styleable>
</resources>

(2)新建自定义的FontTextView类

这个类继承自TextView类,没啥特别的,就是在调用完父类的构造函数之后执行init()方法设置对应的字体就好啦,关键在于如何得到xml文件中定义的fontType属性值的部分代码。

package hujiawei.xiaojian.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

import hujiawei.xiaojian.R;
import hujiawei.xiaojian.util.FontManager;

public class FontTextView extends TextView {

    private String fontType = "shadow";

    public FontTextView(Context context) {
        super(context);
        init(null, 0);
    }

    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        final TypedArray array = getContext().obtainStyledAttributes(
                attrs, R.styleable.FontTextView, defStyle, 0);

        fontType = array.getString(R.styleable.FontTextView_fontType);
        Typeface font = FontManager.getInstance(getContext().getAssets()).getFont("shadow");
        if (fontType.equalsIgnoreCase("bling")) {
            font = FontManager.getInstance(getContext().getAssets()).getFont("bling");
        } else if (fontType.equalsIgnoreCase("planet")) {
            font = FontManager.getInstance(getContext().getAssets()).getFont("planet");
        }
        setTypeface(font, Typeface.NORMAL);

        array.recycle();
    }

}

仔细看上面的代码你会发现一个FontManager类,这个类是个单例类,专门用来管理字体的,因为加载字体是比较费时的操作。

package hujiawei.xiaojian.util;

import android.content.res.AssetManager;
import android.graphics.Typeface;

import java.util.HashMap;
import java.util.Map;

public class FontManager {

    private static FontManager instance;
    private AssetManager assetManager;
    private Map<String, Typeface> fonts;

    private FontManager(AssetManager assetManager) {
        this.assetManager = assetManager;
        fonts = new HashMap<String, Typeface>();
    }

    public static FontManager getInstance(AssetManager assetManager) {
        if (instance == null) {
            instance = new FontManager(assetManager);
        }
        return instance;
    }

    public Typeface getFont(String asset) {
        if (fonts.containsKey(asset))
            return fonts.get(asset);

        String path = "fonts/" + asset + ".ttf";
        Typeface font = Typeface.createFromAsset(assetManager, path);
        fonts.put(asset, font);

        return font;
    }

}

(3)接着就是新建一个布局文件来测试下效果啦,下面的布局文件的显示效果就是本文开始的那个效果图。

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="polaris.ui.PolarisActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        android:text="@string/hello_world"/>

    <hujiawei.xiaojian.view.FontTextView
        android:id="@+id/bling"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"
        android:text="Bling Font"
        android:textSize="40dp"
        android:textColor="@android:color/holo_orange_dark"
        app:fontType="bling"/>

    <hujiawei.xiaojian.view.FontTextView
        android:id="@+id/planet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/bling"
        android:text="Planet Font"
        android:textSize="40dp"
        android:textColor="@android:color/holo_blue_dark"
        app:fontType="planet"/>

    <hujiawei.xiaojian.view.FontTextView
        android:id="@+id/shadow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/planet"
        android:text="Shadow Font"
        android:textSize="40dp"
        android:textColor="@android:color/holo_green_light"
        app:fontType="shadow"/>

</RelativeLayout>

OK,Enjoy! :-)

Hujiawei is a mobile developer Guangdong, China http://javayhu.me/ 本博客所有文章均为原创,请勿随意转载,如需转载请联系我 (hujiawei090807 AT gmail.com) 我在小专栏有个移动开发技术专栏,不定期分享移动开发的核心技术,总结移动开发的实战经验
所有文章皆为原创,内容制作精良,保证干货满满,欢迎订阅 (https://xiaozhuanlan.com/u/javayhu)
>>> 我最近在Android面试指南小专栏里面写了一篇稿子 [Android面试——算法面试心得] ,欢迎阅读!<<<
下面的二维码是我个人维护的微信公众号“潇涧技术专栏”,会不定期分享移动开发的核心技术,欢迎关注!