编辑:已经过了一段时间,我想补充一下我认为最好的方法,而且还是通过XML!
首先,您需要创建一个新类,覆盖您想要自定义的任何视图(例如,想要具有自定义字体的按钮?扩展Button
)。让我们做一个例子:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
现在,如果您没有一个,请在
res/values/attrs.xml
下添加一个XML文档,并添加以下内容:
<resources>
<!
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!
and which attributes it supports
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
好的,既然这个问题解决了,让我们回到之前提到的parseAttributes()
方法:
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
现在你已经准备好了。你可以为任何属性添加更多的内容(你可以为typefaceStyle添加另一个属性——粗体、斜体等),但现在让我们看看如何使用它:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.yourpackage.name.CustomButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
xmlns:custom
这一行可以是任何内容,但是惯例就是上面所示的。重要的是它必须是独特的,这就是为什么使用包名的原因。现在你只需使用
custom:
前缀来设置自定义属性,以及
android:
前缀来设置 Android 属性。
最后一件事:如果您想在样式(
res/values/styles.xml
)中使用此功能,则不应添加
xmlns:custom
行。只需引用属性名称而不带前缀即可。
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
在Android中使用自定义字体
这应该会有所帮助。基本上,无法在XML中实现这一点,并且据我所知,在代码中也没有更容易的方法来实现它。您可以始终拥有一个setLayoutFont()方法,该方法创建字体类型,然后为每个运行setTypeface()。您只需要在向布局添加新项目时更新它。像下面这样:
public void setLayoutFont() {
Typeface tf = Typeface.createFromAsset(
getBaseContext().getAssets(), "fonts/BPreplay.otf");
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setTypeface(tf);
TextView tv2 = (TextView)findViewById(R.id.tv2);
tv2.setTypeface(tf);
TextView tv3 = (TextView)findViewById(R.id.tv3);
tv3.setTypeface(tf);
}
编辑: 我刚刚开始实现类似的功能,我最终做法是创建了一个这样的函数:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
然后,在onCreate()中使用此方法,将您想要更新的所有TextView传递进去:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
编辑于9/5/12:
由于该文章仍然被浏览和投票,我想添加一个更好、更完整的方法:
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);
public void setFont(ViewGroup group, Typeface font) {
int count = group.getChildCount();
View v;
for(int i = 0; i < count; i++) {
v = group.getChildAt(i);
if(v instanceof TextView || v instanceof Button )
((TextView)v).setTypeface(font);
else if(v instanceof ViewGroup)
setFont((ViewGroup)v, font);
}
}
如果你将它传递给你布局的根节点,它会递归检查该布局中的
TextView
或
Button
视图(或者你在那个if语句中添加的任何其他视图),并设置字体,而无需指定它们的ID。当然,这是假设你想将字体设置为
每个视图。
VIEW
怎么样,而不是分别编写自定义文本视图
和自定义按钮视图
?我的要求是针对每个控件,文本视图只是一个例子。抱歉,我忘记提到它了.. :-( - Prasham