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: