I have added a custom font file to my assets/fonts folder. How do I use it from my XML?
I can use it from code as follows:
TextView text =
Create your customed TextView belong to the font you want to use. In this class, I use a static mTypeface field to cache the Typeface (for better performance)
public class HeliVnTextView extends TextView {
/*
* Caches typefaces based on their file path and name, so that they don't have to be created every time when they are referenced.
*/
private static Typeface mTypeface;
public HeliVnTextView(final Context context) {
this(context, null);
}
public HeliVnTextView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public HeliVnTextView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
if (mTypeface == null) {
mTypeface = Typeface.createFromAsset(context.getAssets(), "HelveticaiDesignVnLt.ttf");
}
setTypeface(mTypeface);
}
}
In xml file:
<java.example.HeliVnTextView
android:id="@+id/textView1"
android:layout_width="0dp"
... />
In java class:
HeliVnTextView title = new HeliVnTextView(getActivity());
title.setText(issue.getName());
Not a good idea to use custom fonts in xml due to this fact that is, you have to do it programmatically to avoid the memory leak!
Here is example code that does this. I have the font defined in a static final variable and the font file is in the assets directory.
public class TextViewWithFont extends TextView {
public TextViewWithFont(Context context, AttributeSet attrs) {
super(context, attrs);
this.setTypeface(MainActivity.typeface);
}
public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setTypeface(MainActivity.typeface);
}
public TextViewWithFont(Context context) {
super(context);
this.setTypeface(MainActivity.typeface);
}
}
UPDATE: https://github.com/chrisjenx/Calligraphy appears to be a superior solution to this.
Maybe you can use reflection to inject/hack your font into the static list of available fonts when your application is created? I am interested in feedback from others if this is a really, really bad idea or if this is a great solution — it seems it is going to be one of those extremes...
I was able to inject my custom typeface into the list of system typefaces with my own font family name, then specifying that custom font family name ("brush-script") as the value of android:FontFamily on a standard TextView worked on my LG G4 running Android 6.0.
public class MyApplication extends android.app.Application
{
@Override
public void onCreate()
{
super.onCreate();
Typeface font = Typeface.createFromAsset(this.getResources().getAssets(),"fonts/brush-script.ttf");
injectTypeface("brush-script", font);
}
private boolean injectTypeface(String fontFamily, Typeface typeface)
{
try
{
Field field = Typeface.class.getDeclaredField("sSystemFontMap");
field.setAccessible(true);
Object fieldValue = field.get(null);
Map<String, Typeface> map = (Map<String, Typeface>) fieldValue;
map.put(fontFamily, typeface);
return true;
}
catch (Exception e)
{
Log.e("Font-Injection", "Failed to inject typeface.", e);
}
return false;
}
}
In my layout
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fancy Text"
android:fontFamily="brush-script"/>