Created
June 3, 2016 11:33
-
-
Save orwir/6df839e3527647adc2d56bfadfaad805 to your computer and use it in GitHub Desktop.
Android: change fonts for the whole application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() {} | |
} |
If we use reflections to achieve this, Will google play store reject the app during publishing?
Hi. Nope. But this solution pretty old and I wouldn't recommend it anyway. Custom fonts supported now out of the box.
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?
@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
If we use reflections to achieve this, Will google play store reject the app during publishing?