由于最近的项目需要改变字体,所以用到了现在的方法,下面的总结是从网上整理出来的。但是还是比较好用的。希望能帮助大家省些时间。
public
class
Y_fonts
extends
Activity {
/** Called when the activity is first created. */
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*
* 必须事先在assets底下创建一fonts文件夹 并放入要使用的字体文件(.ttf)
* 并提供相对路径给creatFromAsset()来创建Typeface对象
*/
Typeface fontFace = Typeface.createFromAsset(getAssets(),
"fonts/STXINGKA.TTF");
// 字体文件必须是true type font的格式(ttf);
// 当使用外部字体却又发现字体没有变化的时候(以 Droid Sans代替),通常是因为
// 这个字体android没有支持,而非你的程序发生了错误
TextView text = (TextView) findViewById(R.id.ttf);
text.setTypeface(fontFace);
}
}
做
Android
开发的时候,一些软件会要求一些特殊字体,我们需要引入外部的ttf格式的字体到程序中,具体操作步骤为:
在
安卓
应用程序的目录assets中新建fonts目录,将我们需要使用的ttf字体文件复制进去,然后代码:
// 得到TextView控件对象
TextView textView =
(TextView) findViewById(R.id.custom);
// 将字体文件保存在assets/fonts/目录下,www.linuxidc.com创建Typeface对象
Typeface typeFace = Typeface.createFromAsset(getAssets(),"fonts/DroidSansThai.ttf"
);
// 应用字体
textView.setTypeface(typeFace);
如果想整个页面都使用同样的字体,可以使用批处理,新增一个Java类,如下:
public
class
FontManager {
public
static
void
changeFonts(ViewGroup root, Activity act) {
Typeface tf = Typeface.createFromAsset(act.getAssets(),
"fonts/xxx.ttf");
for
(int
i = 0; i < root.getChildCount(); i++) {
View v = root.getChildAt(i);
if
(v instanceof
TextView) {
((TextView) v).setTypeface(tf);
} else
if
(v instanceof
Button) {
((Button) v).setTypeface(tf);
} else
if
(v instanceof
EditText) {
((EditText) v).setTypeface(tf);
} else
if
(v instanceof
ViewGroup) {
changeFonts((ViewGroup) v, act);
}
}
}
}
转载请注明 作者:田野光 地址:
http://blog.csdn.net/lovefish2/article/details/46129527
在应用开发中,或许你会听到设计狮和产品锦鲤这样抱怨,
安卓
原生的字体太丑啦,傻大笨粗啊,有没有办法换成细体啊…?不幸的是,安卓字体确实傻大笨粗,其次,只有normal和bold,没有light啊.如果更不幸的是,你看不上安卓可以切换的几种字体,一定要使用自己的字体文件时,该怎么办呢?下面介绍三种方法,让应用换上新的字体.
(注: 前两种方法都有局限性,想要替换整个应用字体的,直接看第三种方法, 对
Android
Lollipop同样支持)
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); }}
我们会发现,第一种方法其实只适用于局部位置修改字体,例如整个布局页面都像要设置自定义字体怎么办呢?我们可以这样做:
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);
//你可以在这里添加自定义字体的其他类型的view
}
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(); } } } }}
例如我们的布局文件是这样的:
<
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
>
我们可以这样修改字体:
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(); } }}
然后在主题里指定使用某种字体(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
style
>
<
style
name
=
"CustomTextAppearance"
>
<
item
name
="
android:typeface"
>
monospace
item
>
style
>
resources
>
最后在你的Application的onCreate()方法里面使用:
FontsOverride.setDefaultFont(
this
,
"MONOSPACE"
,
"fonts/MyFont.ttf"
);
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) {
//android 5.0及以上我们反射修改Typeface.sSystemFontMap变量
if
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Map 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(); } } }}
//Material主题默认字体为sans-serif,暂时未找到自定义修改字体的方法
FontsOverride.setDefaultFont(
this
,
"sans-serif"
,
"fonts/Roboto-Light.ttf"
);
- 其他方法: 如使用第三方库Calligraphy, 我没使用过,如果有感兴趣的可以自己尝试一下.