Create a new Android project and create in the values folder the attributes.xml file, in order to define the attribute font (this will be used in xml configuration).
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextViewCustomFont">
<attr name="font" format="string" />
</declare-styleable>
</resources>
Then we need to extend the TextView class with our customization:
package com.devsourcenter;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.TextView;
import com.devsourcenter.textviewwithcustomfont.R;
public class TextViewCustomFont extends TextView {
public TextViewCustomFont(Context context, AttributeSet attributes) {
super(context, attributes);
// attributes variable contains all the attributes defined in the xml file
// typedArray contains only the attribute specified by the resource TextViewCustomFont
TypedArray typedArray = context.obtainStyledAttributes(attributes,
R.styleable.TextViewCustomFont);
// get the font attribute from xml
String fontPath = typedArray
.getString(R.styleable.TextViewCustomFont_font);
// if the attribute is present it is set as font
if (fontPath != null) {
AssetManager assetManager = context.getResources().getAssets();
// this is the object related to the font
Typeface typeface = Typeface
.createFromAsset(assetManager, fontPath);
// now the assign the font to the TextView
setTypeface(typeface);
typedArray.recycle();
}
}
/**
* Assign the font in fontPath to the TextView
*
* @param fontPath
* Path of the font file in assets folder
*/
public void setFont(@Nullable String fontPath) {
AssetManager assetManager = getContext().getResources().getAssets();
Typeface typeface = Typeface.createFromAsset(assetManager, fontPath);
setTypeface(typeface);
}
}
The
setFont method is used to set the font programmatically, while the constructor checks if the font is specified in the xml file. Now we can include TextViewCustomFont in our activity layout (activity_main.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res/com.devsourcenter.textviewwithcustomfont"
tools:context="com.devsourcenter.textviewwithcustomfont.MainActivity" >
<!-- we set the font in xml with attribute font -->
<com.devsourcenter.TextViewCustomFont
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:font="fonts/palatino.ttf"
android:text="@string/palatino"
android:textSize="40sp" />
<!-- in this view we set the font programmatically -->
<com.devsourcenter.TextViewCustomFont
android:id="@+id/courier_new_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/courier_new"
android:textSize="40sp" />
</LinearLayout>
In the first TextView we set the font with the xml custom attribute font (we declared the namespace for the prefix
app to use the attribute), otherwise the font of the second TextView is changed directly in the Activity:
package com.devsourcenter.textviewwithcustomfont;
import com.devsourcenter.TextViewCustomFont;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextViewCustomFont customTextView =
(TextViewCustomFont) findViewById(R.id.courier_new_text_view);
// set font programmatically
customTextView.setFont("fonts/courierNew.ttf");
}
}
As shown above we put the fonts courierNew.ttf and palatino.ttf in the assets/fonts folder. The running activity looks like this:
