Setting custom font through XML with DataBinding

Today we will learn about setting custom font through XML with DataBinding. We already know how to set custom font through java code.
1 2 |
Typeface custom_font = Typeface.createFromAsset(getAssets(), "fonts/font name.ttf"); tv.setTypeface(custom_font); |
It will set font type for given TextView or other View. But what if we have more number of TextViews/EditTexts throughout the application and that also with multiple custom fonts? We need to declare those number of objects for TextView/EditText as well as for TypeFace declaration. Don’t you think it will increase number of codes? Yes, so other option will come in your mind is to create Custom TextView/EditText. Not a bad idea but we have 15-20 custom fonts throughout the app so creating those number of Custom class would realy be a bad idea. So what is the simplest and easy solution? Answer is DataBinding.
Yes with the help of DataBinding you will be able to set custom font with just one line and that also without creating any object of TextView/EditText. sounds interesting? Let’s follow step by step instruction to implement that :
Step 1 : Implement DataBinding in your android studio project, refer previous tutorial to setup DataBinding “Working with DataBinding Android“.
Step 2 : Create custom class for storing and accessing custom fonts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class CustomFontFamily { static CustomFontFamily customFontFamily; HashMap<String,String> fontMap=new HashMap<>(); public static CustomFontFamily getInstance() { if(customFontFamily==null) customFontFamily=new CustomFontFamily(); return customFontFamily; } public void addFont(String alias, String fontName){ fontMap.put(alias,fontName); } public Typeface getFont(String alias) { String fontFilename = fontMap.get(alias); if (fontFilename == null) { Log.e("", "Font not available with name " + alias); return null; } else { Typeface typeface = Typeface.createFromAsset(CustomApplication.getContext().getAssets(), "fonts/" + fontFilename); return typeface; } } } |
Step 3 : Define custom font in Applicaiton class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class CustomApplication extends Application { private static Context context; CustomFontFamily customFontFamily; @Override public void onCreate() { super.onCreate(); CustomApplication.context=this; customFontFamily=CustomFontFamily.getInstance(); // add your custom fonts here with your own custom name. customFontFamily.addFont("amatic","AmaticSC-Regular.ttf"); customFontFamily.addFont("pacific","Pacifico.ttf"); customFontFamily.addFont("seasrn","SEASRN.ttf"); customFontFamily.addFont("capture","Capture_it.ttf"); customFontFamily.addFont("xcelsion","Xcelsion_Italic.ttf"); } public static Context getContext() { return context; } } |
Note : All the fonts defined in Application class must be available under asstes/fonts folder.
Step 4 : Write Binding class to use fonts through out the application.
1 2 3 4 5 6 7 |
public class FontBinding { @BindingAdapter({"bind:font"}) public static void setFont(TextView textView, String fontName) { textView.setTypeface(CustomFontFamily.getInstance().getFont(fontName)); } } |
Step 5 : Access fonts from xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Welcome to AndroidGig" android:textAllCaps="true" android:textAppearance="?android:attr/textAppearanceLarge" app:font="@{`amatic`}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Welcome to AndroidGig" android:textAllCaps="true" android:textAppearance="?android:attr/textAppearanceLarge" app:font="@{`pacific`}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Welcome to AndroidGig" android:textAllCaps="true" android:textAppearance="?android:attr/textAppearanceLarge" app:font="@{`seasrn`}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Welcome to AndroidGig" android:textAllCaps="true" android:textAppearance="?android:attr/textAppearanceLarge" app:font="@{`capture`}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Welcome to AndroidGig" android:textAllCaps="true" android:textAppearance="?android:attr/textAppearanceMedium" app:font="@{`xcelsion`}" /> </LinearLayout> </layout> |
Step 6 : Final step is to bind your activity with a view.
1 2 3 4 5 |
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DataBindingUtil.setContentView(this, R.layout.activity_main); } |
Above code will work perfectly but it will create object of TypeFace each time we set font. What we will do next is to store that TypeFace in cache, so next time it will take TapeFace from cache instead of creating new object. There will be minor change you need to do in your CustomFontFamily.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public class CustomFontFamily { static CustomFontFamily customFontFamily; HashMap<String,String> fontMap=new HashMap<>(); HashMap<String,Typeface> fontCache=new HashMap<>(); public static CustomFontFamily getInstance() { if(customFontFamily==null) customFontFamily=new CustomFontFamily(); return customFontFamily; } public void addFont(String alias, String fontName){ fontMap.put(alias,fontName); } public Typeface getFont(String alias) { String fontFilename = fontMap.get(alias); if (fontFilename == null) { Log.e("", "Font not available with name " + alias); return null; } if(fontCache.containsKey(alias)) return fontCache.get(alias); else { Typeface typeface = Typeface.createFromAsset(CustomApplication.getContext().getAssets(), "fonts/" + fontFilename); fontCache.put(fontFilename, typeface); return typeface; } } } |
Now whenever there is new TypeFace object created it will be stored in HashMap so next time it will be taken from map object. You will love this FontBinding Library by Lisa Wray.
Download source code
Ravi Rupareliya
Latest posts by Ravi Rupareliya (see all)
- Dialogflow Entities With Actions on Google - May 7, 2020
- Actions on Google Using Cloud Functions - February 3, 2020
- Create WhatsApp Stickers Android Application - April 19, 2019