Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Android: change fonts for the whole application
public class FontsReplacer {
@SuppressWarnings("unchecked")
public static void replaceFonts(Context context) {
try {
//we need to change all static fields contains fonts:
//1. static constants
setStaticFinalField(Typeface.class, "DEFAULT", FontCache.getTypeface(context, Typeface.NORMAL));
setStaticFinalField(Typeface.class, "DEFAULT_BOLD", FontCache.getTypeface(context, Typeface.BOLD));
setStaticFinalField(Typeface.class, "SANS_SERIF", FontCache.getTypeface(context, Typeface.NORMAL));
setStaticFinalField(Typeface.class, "SERIF", FontCache.getTypeface(context, Typeface.NORMAL));
setStaticFinalField(Typeface.class, "MONOSPACE", FontCache.getTypeface(context, Typeface.NORMAL));
//2. array with defaults
setStaticFinalField(Typeface.class, "sDefaults", new Typeface[] {
Typeface.DEFAULT,
Typeface.DEFAULT_BOLD,
FontCache.getTypeface(context, Typeface.ITALIC),
FontCache.getTypeface(context, Typeface.BOLD_ITALIC)
});
//3. invoke method 'setDefault'
Method setDefault = Typeface.class.getDeclaredMethod("setDefault", Typeface.class);
setDefault.setAccessible(true);
setDefault.invoke(null, Typeface.DEFAULT);
//4. replace fonts in the map
Field sSystemFontMapField = Typeface.class.getDeclaredField("sSystemFontMap");
sSystemFontMapField.setAccessible(true);
Map<String, Typeface> sSystemFontMap = (Map<String, Typeface>) sSystemFontMapField.get(null);
for (String key : sSystemFontMap.keySet()) {
sSystemFontMap.put(key, FontCache.getDefaultTypeface(context));
}
} catch (Exception e) {
Timber.e(e, e.getMessage());
}
}
private static void setStaticFinalField(Class clazz, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
try {
Field modifiers = Field.class.getDeclaredField("accessFlags");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
} catch (Exception e) {
Timber.e(e, e.getMessage());
}
field.set(null, value);
}
private FontsReplacer() {}
}
@jamshadinho
Copy link

jamshadinho commented May 19, 2021

is it possible to replace system font? i am not setting typeface in styles, my requirement is based on some parameter i need to set font, if the parameter is not set i need to set android system font. is that possible?

@orwir
Copy link
Author

orwir commented Aug 17, 2021

@jamshadinho this one is obsolete. Custom fonts supported now of of the box.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment