Android开发 为应用设置自定义字体转载请注明作者 田野光地址 http blog csdn net lovefish2 article details 在应用开发中 或许你会听到设计狮和产品锦鲤这样抱怨 安卓原生的字体太丑啦 傻大笨粗啊 有没有办法换成细体啊 不幸的是 安卓字体确实傻大笨粗 其次 只有 normal 和 bold 没有 light 啊 如果更不幸的是 你看不上安卓可以切换的几种字体 一定要使 安卓应用自定义字体 fonttextview 写在在哪里
转载请注明 作者:田野光 地址:Android开发 为应用设置自定义字体
在应用开发中,或许你会听到设计狮和产品锦鲤这样抱怨,安卓原生的字体太丑啦,傻大笨粗啊,有没有办法换成细体啊…?不幸的是,安卓字体确实傻大笨粗,其次,只有normal和bold,没有light啊.如果更不幸的是,你看不上安卓可以切换的几种字体,一定要使用自己的字体文件时,该怎么办呢?下面介绍三种方法,让应用换上新的字体.
(注: 前两种方法都有局限性,想要替换整个应用字体的,直接看第三种方法, 对Android Lollipop同样支持)
- 方法一: 自定义view
1. 首先, 把你的字体文件放在src/main/assets/fonts 下( /fonts 目录手动新建)
2. 自定义view继承TextView, 使用自定义view就可以啦
public class CustomFontTextView extends TextView {
public CustomFontTextView(Context context) {
super(context);
init(context);
}
public CustomFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomFontTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public void init(Context context) {
Typeface newFont = Typeface.createFromAsset(context.getAssets(), "fonts/MyFont.ttf");
setTypeface(newFont);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 方法二: 遍历viewGroup
我们会发现,第一种方法其实只适用于局部位置修改字体,例如整个布局页面都像要设置自定义字体怎么办呢?我们可以这样做:
public class FontHelper {
public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect) {
if (mContainer == null || mFont == null) return;
for (int i = 0; i < mContainer.getChildCount(); ++i) {
final View mChild = mContainer.getChildAt(i);
if (mChild instanceof TextView) {
((TextView) mChild).setTypeface(mFont);
} else if (mChild instanceof EditText) {
((EditText) mChild).setTypeface(mFont);
} else if (mChild instanceof ViewGroup) {
setAppFont((ViewGroup) mChild, mFont, true);
} else if (reflect) {
try {
Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
mSetTypeface.invoke(mChild, mFont);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
例如我们的布局文件是这样的:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="字体 123 ABC" android:textColor="@android:color/black" android:textSize="40dp"/>
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="字体 123 ABC" android:textColor="@android:color/black" android:textSize="40dp"/>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="字体 123 ABC" android:textColor="@android:color/black" android:textSize="40dp"/>
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="字体 123 ABC" android:textColor="@android:color/black" android:textSize="40dp"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="字体 123 ABC" android:textColor="@android:color/black" android:textSize="40dp" android:typeface="sans"/>
</LinearLayout>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
我们可以这样修改字体:
final Typeface mFont = Typeface.createFromAsset(getAssets(),
"fonts/Roboto-Light.ttf")
final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView()
FontHelper.setAppFont(mContainer, mFont, true)
其实这个方法才是我们绝大多数数时候想要用的, 一次性替换应用全部字体.
由于官方并没有提供相应的接口,所以这里我们采用的方式时通过反射,获取Typeface类的静态成员变量,并修改对应的字体文件.
这里根据你使用的主题和API的不同,处理方式也有所区别:
比如你使用的是Theme.Holo主题,或Theme.AppCompat主题, 首先定义一个工具:
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected static void replaceFont(String staticTypefaceFieldName,
final Typeface newTypeface) {
try {
final Field staticField = Typeface.class
.getDeclaredField(staticTypefaceFieldName);
staticField.setAccessible(true);
staticField.set(null, newTypeface);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
然后在主题里指定使用某种字体(android lollipop设置有区别):
values
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style>
<style name="AppTheme" parent="AppBaseTheme"> <item name="android:typeface">monospace</item> </style>
</resources>
values-v21
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light"> <item name="android:textAppearance">@style/CustomTextAppearance </item> </style>
<style name="CustomTextAppearance"> <item name="android:typeface">monospace</item> </style>
</resources>
最后在你的Application的onCreate()方法里面使用:
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/MyFont.ttf");
- 使用Theme.Material主题
Theme.Material主题是Android 5.0新增的主题
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected static void replaceFont(String staticTypefaceFieldName,
final Typeface newTypeface) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Map<String, Typeface> newMap = new HashMap<>();
newMap.put(staticTypefaceFieldName, newTypeface);
try {
final Field staticField = Typeface.class
.getDeclaredField("sSystemFontMap");
staticField.setAccessible(true);
staticField.set(null, newMap);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
} else {
try {
final Field staticField = Typeface.class
.getDeclaredField(staticTypefaceFieldName);
staticField.setAccessible(true);
staticField.set(null, newTypeface);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
FontsOverride.setDefaultFont(this, "sans-serif", "fonts/Roboto-Light.ttf");
- 其他方法: 如使用第三方库Calligraphy, 我没使用过,如果有感兴趣的可以自己尝试一下.
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/106349.html