Android自定义字体教程
在本教程中,我们将说明如何在应用程序的TextViews和Buttons中设置android自定义字体。
Android自定义字体
Android SDK带有一组标准字体,可以使用一些XML属性来设置样式。
让我们看看它们。
- android:fontFamily:用于更改应用程序的默认字体。
我们可以从以下类型中选择字体。
默认的fontFamily是sans-serif。
android:fontFamily要求的最低API级别为16。
android:typeface:如果已经使用了fontFamily,则此XML属性无效(除非API级别小于15,在这种情况下,fontFamily属性将被忽略)。
normal或者sans是此属性的默认类型。
以下是可接受的值。android:textStyle:此属性可以单独或者结合使用值:粗体,斜体和正常,例如android:textStyle =" bold | italic""。
让我们合并" android:fontFamily"和" android:textStyle",并显示TextView的不同变体。
下面给出了包含不同样式变体的styles.xml。
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="Regular">
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif</item>
</style>
<style name="Italic">
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">italic</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif</item>
</style>
<style name="Bold">
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif</item>
</style>
<style name="BoldItalic">
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold|italic</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif</item>
</style>
<style name="RegularCondensed">
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif-condensed</item>
</style>
<style name="ItalicCondensed">
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">italic</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif-condensed</item>
</style>
<style name="BoldCondensed">
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">28sp</item>
<item name="android:text">sans-serif-condensed</item>
</style>
<style name="Casual">
<item name="android:fontFamily">casual</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">28sp</item>
<item name="android:text">Casual</item>
</style>
<style name="Cursive">
<item name="android:fontFamily">cursive</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">28sp</item>
<item name="android:text">Cursive</item>
</style>
<style name="RegularMono">
<item name="android:fontFamily">monospace</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">28sp</item>
<item name="android:text">mono space</item>
</style>
<style name="ItalicMono">
<item name="android:fontFamily">monospace</item>
<item name="android:textStyle">italic</item>
<item name="android:textSize">28sp</item>
<item name="android:text">monospace</item>
</style>
<style name="BoldMono">
<item name="android:fontFamily">monospace</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">28sp</item>
<item name="android:text">monospace</item>
</style>
<style name="RegularMonoSerif">
<item name="android:fontFamily">serif-monospace</item>
<item name="android:textStyle">normal</item>
<item name="android:textSize">28sp</item>
<item name="android:text">serif-monospace</item>
</style>
<style name="ItalicMonoSerif">
<item name="android:fontFamily">serif-monospace</item>
<item name="android:textStyle">italic</item>
<item name="android:textSize">28sp</item>
<item name="android:text">serif-monospace</item>
</style>
<style name="BoldMonoSerif">
<item name="android:fontFamily">serif-monospace</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">28sp</item>
<item name="android:text">serif-monospace</item>
</style>
</resources>
下面给出activity_main.xml。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/activity_main"
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"
android:orientation="vertical"
tools:context="com.theitroad.customfonts.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Regular"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Italic"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Bold"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/RegularCondensed"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/ItalicCondensed"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/BoldCondensed"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Casual"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Cursive"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/RegularMono"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/ItalicMono"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/BoldMono"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/RegularMonoSerif"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/ItalicMonoSerif"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/BoldMonoSerif"
</LinearLayout>
若要在TextView/Button/EditText对象上设置自定义字体,请使用Typeface属性。
Typeface类指定字体的字体和固有样式。
要在TextView上设置字体,我们调用方法setTypeface()。
以下是可以使用的Typeface常量。
- BOLD
- BOLD_ITALIC
- ITALIC
- NORMAL
要在我们的视图上设置自定义字体,我们首先需要将字体文件导入到我们的项目中。
字体文件通常以.ttf(真字体)和.otf(开放字体)两种类型出现。
Android自定义字体代码
我们创建了另一个布局,即" activity_custom_fonts.xml",用于在视图上设置自定义字体。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/activity_main"
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"
android:orientation="vertical"
tools:context="com.theitroad.customfonts.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amble Bold"
android:textSize="28sp"
android:id="@+id/ambleBold"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amble Light"
android:textSize="28sp"
android:id="@+id/ambleLight"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amble Regular"
android:textSize="28sp"
android:id="@+id/ambleRegular"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenSans Regular"
android:textSize="28sp"
android:id="@+id/opRegular"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenSans-Italic"
android:id="@+id/opItalic"
android:textSize="28sp"
<Button android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Pacifico"
android:id="@+id/pacifico"
</LinearLayout>
我们正在Java代码中设置自定义字体。
MainActivity.java在下面给出
public class MainActivity extends AppCompatActivity {
TextView ambleBold, ambleLight, ambleRegular, openSansItalic, openSansRegular;
Button btn;
private String A_BOLD= "Amble-Bold.ttf";
private String A_LIGHT="Amble-Light.ttf";
private String A_REGULAR= "Amble-Regular.ttf";
private String O_ITALIC= "OpenSans-Italic.ttf";
private String O_REGULAR="OpenSans-Regular.ttf";
private String P_REGULAR="Pacifico.ttf";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_fonts);
ambleBold=(TextView)findViewById(R.id.ambleBold);
ambleLight=(TextView)findViewById(R.id.ambleLight);
ambleRegular=(TextView)findViewById(R.id.ambleRegular);
openSansRegular=(TextView)findViewById(R.id.opRegular);
openSansItalic=(TextView)findViewById(R.id.opItalic);
btn=(Button)findViewById(R.id.pacifico);
ambleBold.setTypeface(Typeface.createFromAsset(getAssets(), A_BOLD));
ambleLight.setTypeface(Typeface.createFromAsset(getAssets(), A_LIGHT));
ambleRegular.setTypeface(Typeface.createFromAsset(getAssets(), A_REGULAR));
openSansRegular.setTypeface(Typeface.createFromAsset(getAssets(), O_REGULAR));
openSansItalic.setTypeface(Typeface.createFromAsset(getAssets(), O_ITALIC));
btn.setTypeface(Typeface.createFromAsset(getAssets(), P_REGULAR));
}
}
在上面的代码中,我们在Typeface类上调用createFromAsset()方法来创建Typeface的新实例。
通过将getAssets()作为第一个参数来调用应用程序AssetManager的实例。
自定义字体资产文件路径在第二个参数中作为字符串传递。
由于我们已将字体文件放置在资产目录的根目录中,因此只需传递字体文件名即可。
注意:使用android:typeface设置外部字体无效
当应用程序运行时,我们最终得到以下输出。
为每个视图分别设置字体是一项耗时且冗长的工作吗?我们需要更好的选择。
我们的答案在于自定义视图。
在下一节中,我们将创建一个Custom TextView类并定义自定义XML属性,以在XML布局本身中设置外部字体。
我们更新的项目结构如下
在实现CustomTextView.java之前,让我们看一下" TypeFactory.java"类,如下所示。
public class TypeFactory {
private String A_BOLD= "Amble-Bold.ttf";
private String A_LIGHT="Amble-Light.ttf";
private String A_REGULAR= "Amble-Regular.ttf";
private String O_ITALIC= "OpenSans-Italic.ttf";
private String O_REGULAR="OpenSans-Regular.ttf";
Typeface ambleBold;
Typeface ambleLight;
Typeface ambleRegular;
Typeface openSansItalic;
Typeface openSansRegular;
public TypeFactory(Context context){
ambleBold = Typeface.createFromAsset(context.getAssets(),A_BOLD);
ambleLight = Typeface.createFromAsset(context.getAssets(),A_LIGHT);
ambleRegular = Typeface.createFromAsset(context.getAssets(),A_REGULAR);
openSansItalic = Typeface.createFromAsset(context.getAssets(),O_ITALIC);
openSansRegular = Typeface.createFromAsset(context.getAssets(),O_REGULAR);
}
}
上面的代码实际上为每个字体文件创建了一个自定义字体。
现在,我们可以在CustomTextView中使用类变量来相应地设置字体。
下面给出了CustomTextView.java类。
public class CustomTextView extends TextView {
private int typefaceType;
private TypeFactory mFontFactory;
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
applyCustomFont(context, attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
applyCustomFont(context, attrs);
}
public CustomTextView(Context context) {
super(context);
}
private void applyCustomFont(Context context, AttributeSet attrs) {
TypedArray array = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomTextView,
0, 0);
try {
typefaceType = array.getInteger(R.styleable.CustomTextView_font_name, 0);
} finally {
array.recycle();
}
if (!isInEditMode()) {
setTypeface(getTypeFace(typefaceType));
}
}
public Typeface getTypeFace(int type) {
if (mFontFactory == null)
mFontFactory = new TypeFactory(getContext());
switch (type) {
case Constants.A_BOLD:
return mFontFactory.ambleBold;
case Constants.A_LIGHT:
return mFontFactory.ambleLight;
case Constants.A_REGULAR:
return mFontFactory.ambleRegular;
case Constants.O_LIGHT:
return mFontFactory.openSansItalic;
case Constants.O_REGULAR:
return mFontFactory.openSansRegular;
default:
return mFontFactory.ambleBold;
}
}
public interface Constants {
int A_BOLD = 1,
A_LIGHT = 2,
A_REGULAR = 3,
O_LIGHT = 4,
O_REGULAR=5;
}
}
如下所示,在attrs.xml文件中定义了" R.styleable.CustomTextView"。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomTextView">
<attr name="font_name">
<enum value="1" name="ambleBold"
<enum value="2" name="ambleLight"
<enum value="3" name="ambleRegular"
<enum value="4" name="openSansItalic"
<enum value="5" name="openSansRegular"
</attr>
</declare-styleable>
</resources>
属性font_name是我们将在XML布局中使用的自定义属性。
下面是更新后的activity_custom_fonts.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
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"
android:orientation="vertical"
tools:context="com.theitroad.customfonts.MainActivity">
<com.theitroad.customfonts.CustomTextView
app:font_name="ambleBold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amble Bold"
android:textSize="28sp"
android:id="@+id/ambleBold"
<com.theitroad.customfonts.CustomTextView
app:font_name="ambleLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amble Light"
android:textSize="28sp"
android:id="@+id/ambleLight"
<com.theitroad.customfonts.CustomTextView
app:font_name="ambleRegular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amble Regular"
android:textSize="28sp"
android:id="@+id/ambleRegular"
<com.theitroad.customfonts.CustomTextView
app:font_name="openSansRegular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenSans Regular"
android:textSize="28sp"
android:id="@+id/opRegular"
<com.theitroad.customfonts.CustomTextView
app:font_name="openSansItalic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenSans-Italic"
android:id="@+id/opItalic"
android:textSize="28sp"
<Button android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Pacifico"
android:id="@+id/pacifico"
</LinearLayout>
现在,MainActivity.java代码仅需要设置Button字体。
注意:可以通过类似方式创建CustomButton自定义视图。

