前言
项目中经常使用到自定义字体,如果每个都在代码中进行设置,就会比较麻烦,所以采用在xml中直接自定以设置字体。
最终调用效果:
xmlns:app="http://schemas.android.com/apk/res-auto"
//通过app:typeface 设置字体
<americanshop.com.americanshop.view.AppTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:typeface="sf_pro_regular" />
步骤
-
把字体添加到assets目录下。
-
修改atters.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomTextView">
<attr name="typeface">
<enum name="sf_pro_bold" value="0"/>
<enum name="sf_pro_bold_italic" value="1"/>
<enum name="sf_pro_heavy" value="2"/>
</attr>
</declare-styleable>
</resources>
attr 的name 即是在xml时用的标签,declare-styleable 的name 用于获取在xml中设置的typeface值。
- 创建自定义TextView
public class AppTextView extends AppCompatTextView {
public static class TypefaceValue{
public static final int Bold = 0;
public static final int BoldItalic = 1;
public static final int Heavy = 2;
}
@IntDef({TypefaceValue.Bold, TypefaceValue.BoldItalic, TypefaceValue.Heavy})
@Retention(RetentionPolicy.SOURCE)
public @interface TypeFace {
}
public AppTextView(Context context) {
this(context,null);
}
public AppTextView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public AppTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
private void init(Context context, AttributeSet attrs) {
Typeface typeface = null;
if (!isInEditMode()){
if(null != attrs){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
typeface = typefaceFromAttrs(context,a);
a.recycle();
}
if (typeface == null){
typeface = FontUtils.getSFProRegular();
}
setTypeface(typeface);
}
}
private Typeface typefaceFromAttrs(Context context, TypedArray a) {
Typeface typeface = null;
if (a.hasValue(R.styleable.CustomTextView_typeface)) {
int typefaceValue = a.getInt(R.styleable.CustomTextView_typeface, TypefaceValue.Regular);
switch (typefaceValue) {
case TypefaceValue.Bold:
typeface = FontUtils.getSFProBold();
break;
case TypefaceValue.BoldItalic:
typeface = FontUtils.getSFProBoldItalic();
break;
case TypefaceValue.Heavy:
typeface = FontUtils.getSFProHeavy();
break;
default:
typeface = FontUtils.getSFProRegular();
}
}
if (typeface == null) {
typeface = FontUtils.getSFProRegular();
}
return typeface;
}
}
- FontUtils封装了对font的读取
public class FontUtils {
private static final Map<String, Typeface> fontMap = new HashMap();
private static Typeface getFontTypefaceFromAssert(String fontName) {
try {
synchronized (fontMap) {
if (!fontMap.containsKey(fontName)) {
Typeface typface = Typeface.createFromAsset(App.getAppComponent().getContext().getAssets(), fontName);
fontMap.put(fontName, typface);
}
Typeface typface = fontMap.get(fontName);
return typface;
}
} catch (Exception e) {
return null;
}
}
public static Typeface getFontTypefaceByName(String fontName) {
return getFontTypefaceFromAssert(fontName);
}
public static Typeface getSFProBold() {
return getFontTypefaceFromAssert("fonts/SF-Pro-Text-Bold.otf");
}
public static Typeface getSFProBoldItalic() {
return getFontTypefaceFromAssert("fonts/SF-Pro-Text-BoldItalic.otf");
}
static public void changeFont(View element, Typeface tf){
if (element instanceof TextView) {
((TextView) element).setTypeface(tf);
}else if(element instanceof EditText){
((EditText)element).setTypeface(tf);
}
}
}