Is it possible to set any custom font in every control of the application? And not necessarily runtime ? (i.e. from xml if possible or only once for whole application in JAVA file)
I can set the font for one control from this code.
public static void setFont(TextView textView) {
Typeface tf = Typeface.createFromAsset(textView.getContext()
.getAssets(), "fonts/BPreplay.otf");
textView.setTypeface(tf);
}
And the problem with this code is it should be called for every control. And i want to call this or any similar method once, or if possible set the property in xml. Is it possible?
EDIT: So it's been a while, and I'd like to add what I think is the best way to do this, and through XML no less!
So first, you're going to want to make a new class that overrides whatever View you want to customize. (e.g. want a Button with a custom typeface? Extend Button). Let's make an example:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs); //I'll explain this method later
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
Now, if you don't have one, add an XML document under res/values/attrs.xml, and add:
<resources>
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!-- Tell Android that the class "CustomButton" can be styled,
and which attributes it supports -->
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
Okay, so with that out of the way, let's get back to the parseAttributes() method from earlier:
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
//The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
//You can instantiate your typeface anywhere, I would suggest as a
//singleton somewhere to avoid unnecessary copies
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
Now you're all set. You can add more attributes for about anything (you could add another one for typefaceStyle -- bold, italic, etc.) but now let's see how to use it:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.yourpackage.name.CustomButton
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
The xmlns:custom line can really be anything, but the convention is what's shown above. What matters is that it is unique, and that's why the package name is used. Now you just use the custom: prefix for your attributes, and the android: prefix for android attributes.
One last thing: if you want to use this in a style (res/values/styles.xml), you should not add the xmlns:custom line. Just reference the name of the attribute with no prefix:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
Using a custom typeface in Android
This should help. Basically, there's no way to do this in XML, and as far as I can tell, no easier way to do it in code. You could always have a setLayoutFont() method that creates the typeface once, then runs setTypeface() for each. You'd just have to update it each time you add a new item to a layout. Something like below:
public void setLayoutFont() {
Typeface tf = Typeface.createFromAsset(
getBaseContext().getAssets(), "fonts/BPreplay.otf");
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setTypeface(tf);
TextView tv2 = (TextView)findViewById(R.id.tv2);
tv2.setTypeface(tf);
TextView tv3 = (TextView)findViewById(R.id.tv3);
tv3.setTypeface(tf);
}
EDIT: So I just got around to implementing something like this myself, and how I ended up doing it was making a function such as this:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
Then, just use this method from onCreate(), and pass all the TextViews you want to update:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
EDIT 9/5/12:
So since this is still getting views and votes, I'd like to add a much better and more complete method:
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);
/*
* Sets the font on all TextViews in the ViewGroup. Searches
* recursively for all inner ViewGroups as well. Just add a
* check for any other views you want to set as well (EditText,
* etc.)
*/
public void setFont(ViewGroup group, Typeface font) {
int count = group.getChildCount();
View v;
for(int i = 0; i < count; i++) {
v = group.getChildAt(i);
if(v instanceof TextView || v instanceof Button /*etc.*/)
((TextView)v).setTypeface(font);
else if(v instanceof ViewGroup)
setFont((ViewGroup)v, font);
}
}
If you pass it the root of your layout, it will recursively check for TextView or Button views (or any others you add to that if statement) within that layout, and set the font without you having to specify them by ID. This of course is assuming you want to set the font to every view.
There is a fairly easy way to do this via XML. You just need to create your own widget that extends TextView.
First, create a file in res/values/attrs.xml with the following content:
<resources>
<declare-styleable name="TypefacedTextView">
<attr name="typeface" format="string" />
</declare-styleable>
</resources>
After that, create your custom widget:
package your.package.widget;
public class TypefacedTextView extends TextView {
public TypefacedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//Typeface.createFromAsset doesn't work in the layout editor. Skipping...
if (isInEditMode()) {
return;
}
TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.TypefacedTextView);
String fontName = styledAttrs.getString(R.styleable.TypefacedTextView_typeface);
styledAttrs.recycle();
if (fontName != null) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), fontName);
setTypeface(typeface);
}
}
}
As you can see, the code above will read a font inside the assets/ folder. For this example, I am assuming that there is a file called "custom.ttf" in the assets folder. At last, use the widget in the XMLs:
<your.package.widget.TypefacedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:your_namespace="http://schemas.android.com/apk/res/your.package"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Custom fonts in XML are easy"
android:textColor="#FFF"
android:textSize="14dip"
your_namespace:typeface="custom.ttf" />
Note: You won't be able to see your custom font in Eclipse's layout editor. This is why I put the isInEditMode() check. But if you run your app, the custom font will work like a charm.
Example of TextView with roboto typeface:
attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RobotoTextView">
<attr name="typeface"/>
</declare-styleable>
<attr name="typeface" format="enum">
<enum name="roboto_thin" value="0"/>
<enum name="roboto_thin_italic" value="1"/>
<enum name="roboto_light" value="2"/>
<enum name="roboto_light_italic" value="3"/>
<enum name="roboto_regular" value="4"/>
<enum name="roboto_italic" value="5"/>
<enum name="roboto_medium" value="6"/>
<enum name="roboto_medium_italic" value="7"/>
<enum name="roboto_bold" value="8"/>
<enum name="roboto_bold_italic" value="9"/>
<enum name="roboto_black" value="10"/>
<enum name="roboto_black_italic" value="11"/>
<enum name="roboto_condensed" value="12"/>
<enum name="roboto_condensed_italic" value="13"/>
<enum name="roboto_condensed_bold" value="14"/>
<enum name="roboto_condensed_bold_italic" value="15"/>
</attr>
</resources>
RobotoTextView.java:
public class RobotoTextView extends TextView {
/*
* Permissible values for the "typeface" attribute.
*/
private final static int ROBOTO_THIN = 0;
private final static int ROBOTO_THIN_ITALIC = 1;
private final static int ROBOTO_LIGHT = 2;
private final static int ROBOTO_LIGHT_ITALIC = 3;
private final static int ROBOTO_REGULAR = 4;
private final static int ROBOTO_ITALIC = 5;
private final static int ROBOTO_MEDIUM = 6;
private final static int ROBOTO_MEDIUM_ITALIC = 7;
private final static int ROBOTO_BOLD = 8;
private final static int ROBOTO_BOLD_ITALIC = 9;
private final static int ROBOTO_BLACK = 10;
private final static int ROBOTO_BLACK_ITALIC = 11;
private final static int ROBOTO_CONDENSED = 12;
private final static int ROBOTO_CONDENSED_ITALIC = 13;
private final static int ROBOTO_CONDENSED_BOLD = 14;
private final static int ROBOTO_CONDENSED_BOLD_ITALIC = 15;
/**
* List of created typefaces for later reused.
*/
private final static SparseArray<Typeface> mTypefaces = new SparseArray<Typeface>(16);
/**
* Simple constructor to use when creating a view from code.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
*/
public RobotoTextView(Context context) {
super(context);
}
/**
* Constructor that is called when inflating a view from XML. This is called
* when a view is being constructed from an XML file, supplying attributes
* that were specified in the XML file. This version uses a default style of
* 0, so the only attribute values applied are those in the Context's Theme
* and the given AttributeSet.
* <p/>
* <p/>
* The method onFinishInflate() will be called after all children have been
* added.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param attrs The attributes of the XML tag that is inflating the view.
* #see #RobotoTextView(Context, AttributeSet, int)
*/
public RobotoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
/**
* Perform inflation from XML and apply a class-specific base style. This
* constructor of View allows subclasses to use their own base style when
* they are inflating.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param attrs The attributes of the XML tag that is inflating the view.
* #param defStyle The default style to apply to this view. If 0, no style
* will be applied (beyond what is included in the theme). This may
* either be an attribute resource, whose value will be retrieved
* from the current theme, or an explicit style resource.
* #see #RobotoTextView(Context, AttributeSet)
*/
public RobotoTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
/**
* Parse the attributes.
*
* #param context The Context the view is running in, through which it can access the current theme, resources, etc.
* #param attrs The attributes of the XML tag that is inflating the view.
*/
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);
int typefaceValue = values.getInt(R.styleable.RobotoTextView_typeface, 0);
values.recycle();
setTypeface(obtaintTypeface(context, typefaceValue));
}
/**
* Obtain typeface.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param typefaceValue values for the "typeface" attribute
* #return Roboto {#link Typeface}
* #throws IllegalArgumentException if unknown `typeface` attribute value.
*/
private Typeface obtaintTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
Typeface typeface = mTypefaces.get(typefaceValue);
if (typeface == null) {
typeface = createTypeface(context, typefaceValue);
mTypefaces.put(typefaceValue, typeface);
}
return typeface;
}
/**
* Create typeface from assets.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param typefaceValue values for the "typeface" attribute
* #return Roboto {#link Typeface}
* #throws IllegalArgumentException if unknown `typeface` attribute value.
*/
private Typeface createTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
Typeface typeface;
switch (typefaceValue) {
case ROBOTO_THIN:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Thin.ttf");
break;
case ROBOTO_THIN_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-ThinItalic.ttf");
break;
case ROBOTO_LIGHT:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Light.ttf");
break;
case ROBOTO_LIGHT_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-LightItalic.ttf");
break;
case ROBOTO_REGULAR:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
break;
case ROBOTO_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Italic.ttf");
break;
case ROBOTO_MEDIUM:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Medium.ttf");
break;
case ROBOTO_MEDIUM_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-MediumItalic.ttf");
break;
case ROBOTO_BOLD:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
break;
case ROBOTO_BOLD_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldItalic.ttf");
break;
case ROBOTO_BLACK:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Black.ttf");
break;
case ROBOTO_BLACK_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BlackItalic.ttf");
break;
case ROBOTO_CONDENSED:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Condensed.ttf");
break;
case ROBOTO_CONDENSED_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-CondensedItalic.ttf");
break;
case ROBOTO_CONDENSED_BOLD:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensed.ttf");
break;
case ROBOTO_CONDENSED_BOLD_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensedItalic.ttf");
break;
default:
throw new IllegalArgumentException("Unknown `typeface` attribute value " + typefaceValue);
}
return typeface;
}
}
Example of use:
<your.package.widget.RobotoTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:typeface="roboto_thin"
android:textSize="22sp"
android:text="Roboto Thin"/>
Resources:
Roboto & Noto fonts
It's too late but my it helps the other
i have created CustomTextView which has an attribute called typeFace and it's care of memory leak problem with typeface loading without caching
Firstly Fonts class which load the fonts from assets for one time only
import android.content.Context;
import android.graphics.Typeface;
import java.util.Hashtable;
/**
* Created by tonyhaddad on 7/19/15.
*/
public class Fonts {
private Context context;
public Fonts(Context context) {
this.context = context;
}
private static Hashtable<String, Typeface> sTypeFaces = new Hashtable<String, Typeface>(
4);
public static Typeface getTypeFace(Context context, String fileName) {
Typeface tempTypeface = sTypeFaces.get(fileName);
if (tempTypeface == null) {
String fontPath=null;
if(fileName=="metabold")
fontPath ="fonts/Meta-Bold.ttf";
else if(fileName=="metanormal")
fontPath="fonts/Meta-Normal.ttf";
else if(fileName=="gsligh")
fontPath="fonts/gesslight.ttf";
else if(fileName=="bold")
fontPath="fonts/Lato-Bold.ttf";
else if(fileName=="rcr")
fontPath="fonts/RobotoCondensed-Regular.ttf";
else if(fileName=="mpr")
fontPath="fonts/MyriadPro-Regular.otf";
else if(fileName=="rr")
fontPath="fonts/Roboto-Regular.ttf";
tempTypeface = Typeface.createFromAsset(context.getAssets(), fontPath);
sTypeFaces.put(fileName, tempTypeface);
}
return tempTypeface;
}
}
then you need to add a custom attribute in the attrs.xml add this
<declare-styleable name="CustomFontTextView">
<attr name="typeFace" format="string" />
</declare-styleable>
then custom class
package package_name;
/**
* Created by tonyhaddad on 8/26/15.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
import package_name.R;
public class CustomFontTextView extends TextView {
String typeFace;
public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) {
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomFontTextView,
0, 0);
try {
typeFace = a.getString(0);
} finally {
a.recycle();
}
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
public CustomFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (isInEditMode()) {
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomFontTextView,
0, 0);
try {
typeFace = a.getString(0);
} finally {
a.recycle();
}
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
public CustomFontTextView(Context context) {
super(context);
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
private void init() {
}
public String getTypeFace() {
return typeFace;
}
public void setTypeFace(String typeFace) {
this.typeFace = typeFace;
invalidate();
requestLayout();
}
}
and finally add the text view
<package_name.CustomFontTextView
xmlns:custom="http://schemas.android.com/apk/res-auto/package_name"
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="41dp"
android:gravity="center_vertical"
android:text="text"
android:textColor="#000"
android:textSize="23sp"
custom:typeFace="metanormal"/>
and you can change the font progrmaticlly with setTypeFace method
also you can move the custom namespace to your parent layout if you want to use more than one from this view
Happy Coding :)
The method below, called in onCreate() and passed your outermost ViewGroup, will work for everything but text that is dynamically created (ie dynamic lists, alerts, etc.). An easy way to get the outermost ViewGroup is to use getRootView on any one of your views.
public void onCreate(Bundle savedInstanceState){
//onCreate code...
EditText text = (EditText) findViewById(R.id.editText1);
setTypeFaceForViewGroup((ViewGroup) text.getRootView());
}
private void setTypeFaceForViewGroup(ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++) {
if (vg.getChildAt(i) instanceof ViewGroup)
setTypeFaceForViewGroup((ViewGroup) vg.getChildAt(i));
else if (vg.getChildAt(i) instanceof TextView)
((TextView) vg.getChildAt(i)).setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Your_Font.ttf"));
}
}
This should work for dynamic content as well, you'd just have to call it, passing in whatever you created, just after you created it (I haven't tested this, though).
To save memory, you'll probably want to make the typeface a static variable, rather than creating a new one each time the loop runs like I have here.
If you are looking for a more general programatic solution, I created a static class that can be used to set the Typeface of an entire view (Activity UI). Note that I am working with Mono (C#) but you can implement it easily using Java.
You can pass this class a layout or a specific view that you want to customize. If you want to be super efficient you could implement it using the Singleton pattern.
public static class AndroidTypefaceUtility
{
static AndroidTypefaceUtility()
{
}
//Refer to the code block beneath this one, to see how to create a typeface.
public static void SetTypefaceOfView(View view, Typeface customTypeface)
{
if (customTypeface != null && view != null)
{
try
{
if (view is TextView)
(view as TextView).Typeface = customTypeface;
else if (view is Button)
(view as Button).Typeface = customTypeface;
else if (view is EditText)
(view as EditText).Typeface = customTypeface;
else if (view is ViewGroup)
SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
else
Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
}
catch (Exception ex)
{
Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
throw ex;
}
}
else
{
Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
}
}
public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
{
if (customTypeface != null && layout != null)
{
for (int i = 0; i < layout.ChildCount; i++)
{
SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
}
}
else
{
Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
}
}
}
In your activity you will need to create a Typeface object. I create mine in the OnCreate() using a .ttf file placed in my Resources/Assets/ directory. Make sure that the file is marked as an Android Asset in its' properties.
protected override void OnCreate(Bundle bundle)
{
...
LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
}
Unfortunately, Android doesn't provide the quick, easy and clean way you're looking for to change the font for your entire app. But recently I've looked into this matter and created some tools that allow you to change the font without any coding (you can do it all through xml, styles and even text appearances). They're based on similar solutions like you see in the other answers here, but allow for far more flexibility. You can read all about it on this blog, and see the github project here.
Here's an example of how to apply these tools. Put all your font files in assets/fonts/. Then, declare those fonts in an xml file (e.g. res/xml/fonts.xml) and load this file early in your app with TypefaceManager.initialize(this, R.xml.fonts); (e.g., in the onCreate of your Application class). The xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<familyset>
<!-- Some Font. Can be referenced with 'someFont' or 'aspergit' -->
<family>
<nameset>
<name>aspergit</name>
<name>someFont</name>
</nameset>
<fileset>
<file>Aspergit.ttf</file>
<file>Aspergit Bold.ttf</file>
<file>Aspergit Italic.ttf</file>
<file>Aspergit Bold Italic.ttf</file>
</fileset>
</family>
<!-- Another Font. Can be referenced with 'anotherFont' or 'bodoni' -->
<family>
<nameset>
<name>bodoni</name>
<name>anotherFont</name>
</nameset>
<fileset>
<file>BodoniFLF-Roman.ttf</file>
<file>BodoniFLF-Bold.ttf</file>
</fileset>
</family>
</familyset>
Now you can use these fonts in your style or xml (provided you use the tools I mentioned above), by using the custom UI element com.innovattic.font.FontTextView in your xml layout. Below you can see how you can apply a font to all texts in your entire app, just by editing res/values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<!-- Application theme -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:textViewStyle">#style/MyTextViewStyle</item>
</style>
<!-- Style to use for ALL text views (including FontTextView) -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="MyTextViewStyle" parent="#android:style/Widget.Holo.Light.TextView">
<item name="android:textAppearance">#style/MyTextAppearance</item>
</style>
<!-- Text appearance to use for ALL text views (including FontTextView) -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="MyTextAppearance" parent="#android:style/TextAppearance.Holo">
<!-- Alternatively, reference this font with the name "aspergit" -->
<!-- Note that only our own TextView's will use the font attribute -->
<item name="flFont">someFont</item>
<item name="android:textStyle">bold|italic</item>
</style>
<!-- Alternative style, maybe for some other widget -->
<style name="StylishFont">
<item name="flFont">anotherFont</item>
<item name="android:textStyle">normal</item>
</style>
</resources>
With the accompanying res/layout/layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!-- This text view is styled with the app theme -->
<com.innovattic.font.FontTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This uses my font in bold italic style" />
<!-- This text view is styled here and overrides the app theme -->
<com.innovattic.font.FontTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:flFont="anotherFont"
android:textStyle="normal"
android:text="This uses another font in normal style" />
<!-- This text view is styled with a style and overrides the app theme -->
<com.innovattic.font.FontTextView
style="#style/StylishFont"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This also uses another font in normal style" />
</LinearLayout>
Don't forget to apply the theme in your Android manifest.
I would like to add a note to the great solution of leocadiotine. It is perfect, but when using this Custom TextView many time slows down the application, since it has to access the assets every time a textview is created. I suggest to use something like the View Holder pattern in the Adapters, i wrote an example:
public class Fonts {
private static final Map<String, Typeface> typefaces = new HashMap<String, Typeface>();
public static Typeface getTypeface(Context ctx, String fontName) {
Typeface typeface = typefaces.get(fontName);
if (typeface == null) {
typeface = Typeface.createFromAsset(ctx.getAssets(), fontName);
typefaces.put(fontName, typeface);
}
return typeface;
}
}
In this way the application access the assets only one time per asset, and it keeps them in memory for further needs.
I don't know if it changes the whole app, but I have managed to change some components that couldn't otherwise be changed by doing this:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Lucida Sans Unicode.ttf");
Typeface.class.getField("DEFAULT").setAccessible(true);
Typeface.class.getField("DEFAULT_BOLD").setAccessible(true);
Typeface.class.getField("DEFAULT").set(null, tf);
Typeface.class.getField("DEFAULT_BOLD").set(null, tf);
I have found step by step information at this link,link: https://github.com/jaydipumaretiya/CustomTypeface/
There are many ways to use typeface correctly in android, you have to put your typeface file in
assets folder under your main directly and can use it run-time.
Other simplest way is use default library to set typeface in your xml file.
I have prefer this custom typeface library to set typeface to TextView, EditText, Button, CheckBox,
RadioButton and AutoCompleteTextView and other wedget in android.
Android 8.0 (API level 26) introduces a new feature, Fonts in XML.You can create a fontfamily file and set it in styles.xml.
To add fonts as resources, perform the following steps in the Android
Studio:
1.Right-click the res folder and go to New > Android resource directory. The New Resource Directory window appears.
2.In the Resource type list, select font, and then click OK. Note: The name of the resource directory must be font.
3.Add your font files in the font folder.
To create a font family, perform the following steps :
1.Right-click the font folder and go to New > Font resource file. The New Resource File window appears.
2.Enter the file name, and then click OK. The new font resource XML opens in the editor.
3.Enclose each font file, style, and weight attribute in the element. The following XML illustrates adding font-related attributes
in the font resource XML:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="#font/lobster_regular" />
<font
android:fontStyle="italic"
android:fontWeight="400"
android:font="#font/lobster_italic" />
</font-family>
Adding fonts to style
Open the styles.xml, and set the fontFamily attribute to the font file
you want to access.
<style name="customfontstyle" parent="#android:style/TextAppearance.Small">
<item name="android:fontFamily">#font/lobster</item>
</style>
Source:Fonts in XML
To use external fonts, first download the font in .tff format
Google font- Roboto
Add the font asset folder as shown in the image below
After the font asset folder is created, copy and paste the downloaded .tff font into the "font" folder. (make sure the name is formatted well. )
Reference the font in your theme.xml or any layout using the android:fontFamily="#font/splashfont" property.
If you want the font to apply to the entire application, set the fontfamily in you theme.xml. This is how you do it in a theme.xml file
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.FishPott" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#color/color_black_level_1</item>
<item name="colorPrimaryVariant">#color/color_black_level_2</item>
<item name="colorOnPrimary">#color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">#color/color_black_level_1</item>
<item name="colorSecondaryVariant">#color/color_black_level_2</item>
<item name="colorOnSecondary">#color/color_white_level_1</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
<item name="android:fontFamily">#font/robotoregular</item>
</style>
Related
in application i can simply define attr.xml into values and use that into design layout. but i can not set this attributes programical into widgets, for example i have this attribute:
<declare-styleable name="ButtonTextStyle">
<attr name="font_button">
<enum name="consolas" value="0" />
<enum name="times" value="1" />
</attr>
</declare-styleable>
and i can use this attribute into xml by:
<com.sample.app.Widgets.ButtonTextStyle
android:id="#+id/btn_way_bill_click"
android:layout_width="fill_parent"
app:font_button="consolas">
now i'm define some Button programical into project and i want to use consolas font defined into font_button by:
button.setTextAppearance(context, R.attr.font_button);
but i get error for this code and i can not resolve problem, i'm define custom class extends from Button like with this:
public class ButtonTextStyle extends Button {
private Context mContext;
public ButtonTextStyle(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
init(attrs, defStyle);
}
public ButtonTextStyle(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init(attrs,-1);
}
public ButtonTextStyle(Context context) {
super(context);
mContext = context;
init(null,-1);
}
private void init(AttributeSet attrs,int defStyle) {
if (!isInEditMode()) {
TypedArray a = mContext.obtainStyledAttributes(attrs,R.styleable.ButtonTextStyle, defStyle, 0);
String str = a.getString(R.styleable.ButtonTextStyle_font_button);
switch (Integer.parseInt(str)) {
case 0:
str = "fonts/consolas.ttf";
break;
case 1:
str = "fonts/times.ttf";
break;
}
setTypeface(FontManager.getInstance(getContext()).loadFont(str));
}
}
}
PROBLEM:
Expected resource of type style
and i can not set for example enum to widgets like with set times font
HOW to set programical this custom class with attribute defined into attr.xml
UPDATED:
my class to add button is below method. i want to set font for it programically:
private void addButton(final CDialog owner, final Dialog dialog, final DialogButton dlgBtn) {
LinearLayout linearLayout = (LinearLayout) dialog.findViewById(R.id.tsw__layerButton);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 70);
//layoutParams.setMargins(11, 0, 8, 0);
Button button = new Button(context);
if (buttonTheme != -1) {
button.setBackgroundResource(buttonTheme);
}
button.setPadding(0,2,0,0);
button.setGravity(Gravity.CENTER);
button.setText(buttonMsg[dlgBtn.ordinal()]);
button.setTextSize(14);
button.setTextColor(G.context.getResources().getColor(R.color.white_text));
button.setWidth(dpToPx(buttonWidth));
//button.setHeight(dpToPx(32));
button.setLayoutParams(layoutParams);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
if (dialogListener != null) {
dialogListener.onCloseDialog(owner, dlgBtn);
}
}
});
linearLayout.addView(button);
}
Maybe this article will help you Android: Set Custom Attributes Programmatically and Via XML. Note, that there should be a style assigned to the R.attr.font_button attribute somewhere (for example in "AppTheme"). Because it's just an attribute, and it holds a reference to a value.
If you assigned a style in "AppTheme":
ButtonTextStyle button = (TextView) findViewById(R.id.btn_way_bill_click);
Resources.Theme themes = getTheme();
TypedValue storedValueInTheme = new TypedValue();
if (themes.resolveAttribute(R.attr.font_button, storedValueInTheme, true))
button.setTextAppearance(storedValueInTheme.data);
Or if you declared your own theme. It can be declared as follows
<resources>
<style name="ConsolasBtn" parent="#android:style/Widget">
<item name="font_button">consolas</item>
</style>
</resources>
Then you need to apply this theme to your button. Try
ButtonTextStyle button = (TextView) findViewById(R.id.btn_way_bill_click);
button.setTextAppearance(this, R.style.ConsolasBtn); // *this* refers to Context
Or try to pass R.style.ConsolasBtn to your constructor ButtonTextStyle(Context context, AttributeSet attrs, int defStyle) as the defStyle argument.
See also Styles and Themes, Resources.Theme, TypedValue, attrs.
I believe the proper way to achieve what you are trying to do is by first declaring an enum attribute...
<declare-styleable name="ButtonTextStyle">
<attr name="font_button" format="enum">
<enum name="consolas" value="0" />
<enum name="times" value="1" />
</attr>
</declare-styleable>
Only change from your original code is the format attribute. Then you can declare those custom style attributes as below...
<com.sample.app.Widgets.ButtonTextStyle
android:id="#+id/btn_way_bill_click"
android:layout_width="fill_parent"
app:font_button="consolas">
but, don't forget to declare the namespace(s) your sub-widget belongs to in the parent layout, otherwise you won't be able to reference the app alias
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.sample.app.Widgets">
and finally, your init method would look something like this...
private void init(AttributeSet attrs,int defStyle) {
if (!isInEditMode()) {
int i = -1;
TypedArray a = mContext.obtainStyledAttributes(attrs,R.styleable.ButtonTextStyle, defStyle, 0);
try{
a.getInt(R.styleable.ButtonTextStyle_font_button, -1);
}
finally{
a.recycle();
}
switch (i) {
case 0:
str = "fonts/consolas.ttf";
break;
case 1:
str = "fonts/times.ttf";
break;
}
setTypeface(FontManager.getInstance(getContext()).loadFont(str));
}
}
Setting the property programmatically
To set that property programmatically, you will need to expose a "setter" method that takes an integer value, then based on that value you can change the type face. To make things easier for consumers of your custom widget you can also define two constants in your class...
public static final int CONSOLAS = 0;
public static final int TIMES = 1;
then define the setter method...
public void setFontButton(int fontButton) {
if (fontButton != CONSOLAS && fontButton != TIMES) {
throw new IllegalArgumentException(
"fontButton must be one of CONSOLAS or TIMES");
}
//load the font and set it here, the same way you did in "init"
}
All you have to do is call that setter method and pass in one of the constants specified...
buttonTextStyle1.setFontButton(ButtonTextStyle.CONSOLAS);
Yet ANOTHER Update
Instead of doing...
Button button = new Button(context);
do...
ButtonTextStyle button = new ButtonTextStyle(context);
and make sure you import the correct class so it can be used in code...
import com.sample.app.Widgets.ButtonTextStyle;
How to change the font in a TextView, as default it's shown up as Arial? How to change it to Helvetica?
First, the default is not Arial. The default is Droid Sans.
Second, to change to a different built-in font, use android:typeface in layout XML or setTypeface() in Java.
Third, there is no Helvetica font in Android. The built-in choices are Droid Sans (sans), Droid Sans Mono (monospace), and Droid Serif (serif). While you can bundle your own fonts with your application and use them via setTypeface(), bear in mind that font files are big and, in some cases, require licensing agreements (e.g., Helvetica, a Linotype font).
EDIT
The Android design language relies on traditional typographic tools
such as scale, space, rhythm, and alignment with an underlying grid.
Successful deployment of these tools is essential to help users
quickly understand a screen of information. To support such use of
typography, Ice Cream Sandwich introduced a new type family named
Roboto, created specifically for the requirements of UI and
high-resolution screens.
The current TextView framework offers Roboto in thin, light, regular
and bold weights, along with an italic style for each weight. The
framework also offers the Roboto Condensed variant in regular and bold
weights, along with an italic style for each weight.
After ICS, android includes Roboto fonts style,
Read more Roboto
EDIT 2
With the advent of Support Library 26, Android now supports custom fonts by
default. You can insert new fonts in res/fonts which can be set to TextViews individually either in XML or programmatically. The default font for the whole application can also be changed by defining it styles.xml The android developer documentation has a clear guide on this here
First download the .ttf file of the font you need (arial.ttf). Place it in the assets folder. (Inside assets folder create new folder named fonts and place it inside it.) Use the following code to apply the font to your TextView:
Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf");
textView.setTypeface(type);
Typeface tf = Typeface.createFromAsset(getAssets(),
"fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);
You might want to create static class which will contain all the fonts. That way, you won't create the font multiple times which might impact badly on performance.
Just make sure that you create a sub-folder called "fonts" under "assets" folder.
Do something like:
public class CustomFontsLoader {
public static final int FONT_NAME_1 = 0;
public static final int FONT_NAME_2 = 1;
public static final int FONT_NAME_3 = 2;
private static final int NUM_OF_CUSTOM_FONTS = 3;
private static boolean fontsLoaded = false;
private static Typeface[] fonts = new Typeface[3];
private static String[] fontPath = {
"fonts/FONT_NAME_1.ttf",
"fonts/FONT_NAME_2.ttf",
"fonts/FONT_NAME_3.ttf"
};
/**
* Returns a loaded custom font based on it's identifier.
*
* #param context - the current context
* #param fontIdentifier = the identifier of the requested font
*
* #return Typeface object of the requested font.
*/
public static Typeface getTypeface(Context context, int fontIdentifier) {
if (!fontsLoaded) {
loadFonts(context);
}
return fonts[fontIdentifier];
}
private static void loadFonts(Context context) {
for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
}
fontsLoaded = true;
}
}
This way, you can get the font from everywhere in your application.
Best practice ever
TextViewPlus.java:
public class TextViewPlus extends TextView {
private static final String TAG = "TextView";
public TextViewPlus(Context context) {
super(context);
}
public TextViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
String customFont = a.getString(R.styleable.TextViewPlus_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
public boolean setCustomFont(Context ctx, String asset) {
Typeface typeface = null;
try {
typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
} catch (Exception e) {
Log.e(TAG, "Unable to load typeface: "+e.getMessage());
return false;
}
setTypeface(typeface);
return true;
}
}
attrs.xml: (Where to place res/values)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextViewPlus">
<attr name="customFont" format="string"/>
</declare-styleable>
</resources>
How to use:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.mypackage.TextViewPlus
android:id="#+id/textViewPlus1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:text="#string/showingOffTheNewTypeface"
foo:customFont="my_font_name_regular.otf">
</com.mypackage.TextViewPlus>
</LinearLayout>
Hope this will help you.
The answers above are correct. Just make sure that you create a sub-folder called "fonts" under "assets" folder if you are using that piece of code.
Another way to consolidate font creation...
public class Font {
public static final Font PROXIMA_NOVA = new Font("ProximaNovaRegular.otf");
public static final Font FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
private final String assetName;
private volatile Typeface typeface;
private Font(String assetName) {
this.assetName = assetName;
}
public void apply(Context context, TextView textView) {
if (typeface == null) {
synchronized (this) {
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), assetName);
}
}
}
textView.setTypeface(typeface);
}
}
And then to use in your activity...
myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);
Mind you, this double-checked locking idiom with the volatile field only works correctly with the memory model used in Java 1.5+.
Best practice is to use Android Support Library version 26.0.0 or above.
STEP 1: add font file
In res folder create new font resource dictionary
Add font file (.ttf, .orf)
For example, when font file will be helvetica_neue.ttf that will generates R.font.helvetica_neue
STEP 2: create font family
In font folder add new resource file
Enclose each font file, style, and weight attribute in the element.
For example:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="#font/helvetica_neue" />
</font-family>
STEP 3: use it
In xml layouts:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/my_font"/>
Or add fonts to style:
<style name="customfontstyle" parent="#android:style/TextAppearance.Small">
<item name="android:fontFamily">#font/lobster</item>
</style>
For more examples you can follow documentation:
Working with fonts
When your font is stored inside res/asset/fonts/Helvetica.ttf use the following:
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf");
txt.setTypeface(tf);
Or, if your font file is stores inside res/font/helvetica.ttf use the following:
Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);
It's a little old, but I improved the class CustomFontLoader a little bit and I wanted to share it so it can be helpfull. Just create a new class with this code.
import android.content.Context;
import android.graphics.Typeface;
public enum FontLoader {
ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");
private final String name;
private Typeface typeFace;
private FontLoader(final String name) {
this.name = name;
typeFace=null;
}
public static Typeface getTypeFace(Context context,String name){
try {
FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
if(item.typeFace==null){
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}
return item.typeFace;
} catch (Exception e) {
return null;
}
}
public static Typeface getTypeFace(Context context,int id){
FontLoader myArray[]= FontLoader.values();
if(!(id<myArray.length)){
return null;
}
try {
if(myArray[id].typeFace==null){
myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");
}
return myArray[id].typeFace;
}catch (Exception e) {
return null;
}
}
public static Typeface getTypeFaceByName(Context context,String name){
for(FontLoader item: FontLoader.values()){
if(name.equalsIgnoreCase(item.name)){
if(item.typeFace==null){
try{
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}catch (Exception e) {
return null;
}
}
return item.typeFace;
}
}
return null;
}
public static void loadAllFonts(Context context){
for(FontLoader item: FontLoader.values()){
if(item.typeFace==null){
try{
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}catch (Exception e) {
item.typeFace=null;
}
}
}
}
}
Then just use this code on you textview:
Typeface typeFace=FontLoader.getTypeFace(context,"arial");
if(typeFace!=null) myTextView.setTypeface(typeFace);
I finally got a very easy solution to this.
use these Support libraries in app level gradle,
compile 'com.android.support:appcompat-v7:26.0.2'
compile 'com.android.support:support-v4:26.0.2'
then create a directory named "font" inside the res folder
put fonts(ttf) files in that font directory, keep in mind the naming conventions [e.g.name should not contain any special character, any uppercase character and any space or tab]
After that, reference that font from xml like this
<Button
android:id="#+id/btn_choose_employee"
android:layout_width="140dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:background="#drawable/rounded_red_btn"
android:onClick="btnEmployeeClickedAction"
android:text="#string/searching_jobs"
android:textAllCaps="false"
android:textColor="#color/white"
android:fontFamily="#font/times_new_roman_test"
/>
In this example, times_new_roman_test is a font ttf file from that font directory
import java.lang.ref.WeakReference;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Typeface;
public class FontsManager {
private static FontsManager instance;
private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();
private static Context context;
private FontsManager(final Context ctx) {
if (context == null) {
context = ctx;
}
}
public static FontsManager getInstance(final Context appContext) {
if (instance == null) {
instance = new FontsManager(appContext);
}
return instance;
}
public static FontsManager getInstance() {
if (instance == null) {
throw new RuntimeException(
"Call getInstance(Context context) at least once to init the singleton properly");
}
return instance;
}
public Typeface getFont(final String assetName) {
final WeakReference<Typeface> tfReference = typefaces.get(assetName);
if (tfReference == null || tfReference.get() == null) {
final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
assetName);
typefaces.put(assetName, new WeakReference<Typeface>(tf));
return tf;
}
return tfReference.get();
}
}
This way, you can create a View which inherits from TextView and calls setTypeface on its constructor.
get font from asset and set to all children
public static void overrideFonts(final Context context, final View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
overrideFonts(context, child);
}
} else if (v instanceof TextView ) {
((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
}
} catch (Exception e) {
}
}
add class FontTextView.java:
public class FontTextView extends TextView {
String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
init(attrs);
}
}
public FontTextView(Context context) {
super(context);
if (!isInEditMode()) {
init(null);
}
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
if (a.getString(R.styleable.FontTextView_font_type) != null) {
String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];
if (fontName != null) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
setTypeface(myTypeface);
}
a.recycle();
}
}
}
}
add to assets library font
add to attrs.xml ,
The numbers should be in the order in array class.
<declare-styleable name="FontTextView">
<attr name="font_type" format="enum">
<enum name="HelveticaNeue" value="0"/>
<enum name="HelveticaNeueLight" value="1"/>
<enum name="motschcc" value="2"/>
<enum name="symbol" value="3"/>
</attr>
Select a font from the list
Android uses the Roboto font, which is a really nice looking font, with several different weights (regular, light, thin, condensed) that look great on high density screens.
Check below link to check roboto fonts:
How to use Roboto in xml layout
Back to your question, if you want to change the font for all of the TextView/Button in your app, try adding below code into your styles.xml to use Roboto-light font:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
......
<item name="android:buttonStyle">#style/MyButton</item>
<item name="android:textViewStyle">#style/MyTextView</item>
</style>
<style name="MyButton" parent="#style/Widget.AppCompat.Button">
<item name="android:textAllCaps">false</item>
<item name="android:fontFamily">sans-serif-light</item>
</style>
<style name="MyTextView" parent="#style/TextAppearance.AppCompat">
<item name="android:fontFamily">sans-serif-light</item>
</style>
And don't forget to use 'AppTheme' in your AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
......
</application>
Maybe something a bit simpler:
public class Fonts {
public static HashSet<String,Typeface> fonts = new HashSet<>();
public static Typeface get(Context context, String file) {
if (! fonts.contains(file)) {
synchronized (this) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
fonts.put(name, typeface);
}
}
return fonts.get(file);
}
}
// Usage
Typeface myFont = Fonts.get("arial.ttf");
(Note this code is untested, but in general this approach should work well.)
Is it possible to set any custom font in every control of the application? And not necessarily runtime ? (i.e. from xml if possible or only once for whole application in JAVA file)
I can set the font for one control from this code.
public static void setFont(TextView textView) {
Typeface tf = Typeface.createFromAsset(textView.getContext()
.getAssets(), "fonts/BPreplay.otf");
textView.setTypeface(tf);
}
And the problem with this code is it should be called for every control. And i want to call this or any similar method once, or if possible set the property in xml. Is it possible?
EDIT: So it's been a while, and I'd like to add what I think is the best way to do this, and through XML no less!
So first, you're going to want to make a new class that overrides whatever View you want to customize. (e.g. want a Button with a custom typeface? Extend Button). Let's make an example:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs); //I'll explain this method later
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
Now, if you don't have one, add an XML document under res/values/attrs.xml, and add:
<resources>
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!-- Tell Android that the class "CustomButton" can be styled,
and which attributes it supports -->
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
Okay, so with that out of the way, let's get back to the parseAttributes() method from earlier:
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
//The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
//You can instantiate your typeface anywhere, I would suggest as a
//singleton somewhere to avoid unnecessary copies
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
Now you're all set. You can add more attributes for about anything (you could add another one for typefaceStyle -- bold, italic, etc.) but now let's see how to use it:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.yourpackage.name.CustomButton
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
The xmlns:custom line can really be anything, but the convention is what's shown above. What matters is that it is unique, and that's why the package name is used. Now you just use the custom: prefix for your attributes, and the android: prefix for android attributes.
One last thing: if you want to use this in a style (res/values/styles.xml), you should not add the xmlns:custom line. Just reference the name of the attribute with no prefix:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
Using a custom typeface in Android
This should help. Basically, there's no way to do this in XML, and as far as I can tell, no easier way to do it in code. You could always have a setLayoutFont() method that creates the typeface once, then runs setTypeface() for each. You'd just have to update it each time you add a new item to a layout. Something like below:
public void setLayoutFont() {
Typeface tf = Typeface.createFromAsset(
getBaseContext().getAssets(), "fonts/BPreplay.otf");
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setTypeface(tf);
TextView tv2 = (TextView)findViewById(R.id.tv2);
tv2.setTypeface(tf);
TextView tv3 = (TextView)findViewById(R.id.tv3);
tv3.setTypeface(tf);
}
EDIT: So I just got around to implementing something like this myself, and how I ended up doing it was making a function such as this:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
Then, just use this method from onCreate(), and pass all the TextViews you want to update:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
EDIT 9/5/12:
So since this is still getting views and votes, I'd like to add a much better and more complete method:
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);
/*
* Sets the font on all TextViews in the ViewGroup. Searches
* recursively for all inner ViewGroups as well. Just add a
* check for any other views you want to set as well (EditText,
* etc.)
*/
public void setFont(ViewGroup group, Typeface font) {
int count = group.getChildCount();
View v;
for(int i = 0; i < count; i++) {
v = group.getChildAt(i);
if(v instanceof TextView || v instanceof Button /*etc.*/)
((TextView)v).setTypeface(font);
else if(v instanceof ViewGroup)
setFont((ViewGroup)v, font);
}
}
If you pass it the root of your layout, it will recursively check for TextView or Button views (or any others you add to that if statement) within that layout, and set the font without you having to specify them by ID. This of course is assuming you want to set the font to every view.
There is a fairly easy way to do this via XML. You just need to create your own widget that extends TextView.
First, create a file in res/values/attrs.xml with the following content:
<resources>
<declare-styleable name="TypefacedTextView">
<attr name="typeface" format="string" />
</declare-styleable>
</resources>
After that, create your custom widget:
package your.package.widget;
public class TypefacedTextView extends TextView {
public TypefacedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//Typeface.createFromAsset doesn't work in the layout editor. Skipping...
if (isInEditMode()) {
return;
}
TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.TypefacedTextView);
String fontName = styledAttrs.getString(R.styleable.TypefacedTextView_typeface);
styledAttrs.recycle();
if (fontName != null) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), fontName);
setTypeface(typeface);
}
}
}
As you can see, the code above will read a font inside the assets/ folder. For this example, I am assuming that there is a file called "custom.ttf" in the assets folder. At last, use the widget in the XMLs:
<your.package.widget.TypefacedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:your_namespace="http://schemas.android.com/apk/res/your.package"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Custom fonts in XML are easy"
android:textColor="#FFF"
android:textSize="14dip"
your_namespace:typeface="custom.ttf" />
Note: You won't be able to see your custom font in Eclipse's layout editor. This is why I put the isInEditMode() check. But if you run your app, the custom font will work like a charm.
Example of TextView with roboto typeface:
attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RobotoTextView">
<attr name="typeface"/>
</declare-styleable>
<attr name="typeface" format="enum">
<enum name="roboto_thin" value="0"/>
<enum name="roboto_thin_italic" value="1"/>
<enum name="roboto_light" value="2"/>
<enum name="roboto_light_italic" value="3"/>
<enum name="roboto_regular" value="4"/>
<enum name="roboto_italic" value="5"/>
<enum name="roboto_medium" value="6"/>
<enum name="roboto_medium_italic" value="7"/>
<enum name="roboto_bold" value="8"/>
<enum name="roboto_bold_italic" value="9"/>
<enum name="roboto_black" value="10"/>
<enum name="roboto_black_italic" value="11"/>
<enum name="roboto_condensed" value="12"/>
<enum name="roboto_condensed_italic" value="13"/>
<enum name="roboto_condensed_bold" value="14"/>
<enum name="roboto_condensed_bold_italic" value="15"/>
</attr>
</resources>
RobotoTextView.java:
public class RobotoTextView extends TextView {
/*
* Permissible values for the "typeface" attribute.
*/
private final static int ROBOTO_THIN = 0;
private final static int ROBOTO_THIN_ITALIC = 1;
private final static int ROBOTO_LIGHT = 2;
private final static int ROBOTO_LIGHT_ITALIC = 3;
private final static int ROBOTO_REGULAR = 4;
private final static int ROBOTO_ITALIC = 5;
private final static int ROBOTO_MEDIUM = 6;
private final static int ROBOTO_MEDIUM_ITALIC = 7;
private final static int ROBOTO_BOLD = 8;
private final static int ROBOTO_BOLD_ITALIC = 9;
private final static int ROBOTO_BLACK = 10;
private final static int ROBOTO_BLACK_ITALIC = 11;
private final static int ROBOTO_CONDENSED = 12;
private final static int ROBOTO_CONDENSED_ITALIC = 13;
private final static int ROBOTO_CONDENSED_BOLD = 14;
private final static int ROBOTO_CONDENSED_BOLD_ITALIC = 15;
/**
* List of created typefaces for later reused.
*/
private final static SparseArray<Typeface> mTypefaces = new SparseArray<Typeface>(16);
/**
* Simple constructor to use when creating a view from code.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
*/
public RobotoTextView(Context context) {
super(context);
}
/**
* Constructor that is called when inflating a view from XML. This is called
* when a view is being constructed from an XML file, supplying attributes
* that were specified in the XML file. This version uses a default style of
* 0, so the only attribute values applied are those in the Context's Theme
* and the given AttributeSet.
* <p/>
* <p/>
* The method onFinishInflate() will be called after all children have been
* added.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param attrs The attributes of the XML tag that is inflating the view.
* #see #RobotoTextView(Context, AttributeSet, int)
*/
public RobotoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
/**
* Perform inflation from XML and apply a class-specific base style. This
* constructor of View allows subclasses to use their own base style when
* they are inflating.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param attrs The attributes of the XML tag that is inflating the view.
* #param defStyle The default style to apply to this view. If 0, no style
* will be applied (beyond what is included in the theme). This may
* either be an attribute resource, whose value will be retrieved
* from the current theme, or an explicit style resource.
* #see #RobotoTextView(Context, AttributeSet)
*/
public RobotoTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
/**
* Parse the attributes.
*
* #param context The Context the view is running in, through which it can access the current theme, resources, etc.
* #param attrs The attributes of the XML tag that is inflating the view.
*/
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);
int typefaceValue = values.getInt(R.styleable.RobotoTextView_typeface, 0);
values.recycle();
setTypeface(obtaintTypeface(context, typefaceValue));
}
/**
* Obtain typeface.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param typefaceValue values for the "typeface" attribute
* #return Roboto {#link Typeface}
* #throws IllegalArgumentException if unknown `typeface` attribute value.
*/
private Typeface obtaintTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
Typeface typeface = mTypefaces.get(typefaceValue);
if (typeface == null) {
typeface = createTypeface(context, typefaceValue);
mTypefaces.put(typefaceValue, typeface);
}
return typeface;
}
/**
* Create typeface from assets.
*
* #param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* #param typefaceValue values for the "typeface" attribute
* #return Roboto {#link Typeface}
* #throws IllegalArgumentException if unknown `typeface` attribute value.
*/
private Typeface createTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
Typeface typeface;
switch (typefaceValue) {
case ROBOTO_THIN:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Thin.ttf");
break;
case ROBOTO_THIN_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-ThinItalic.ttf");
break;
case ROBOTO_LIGHT:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Light.ttf");
break;
case ROBOTO_LIGHT_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-LightItalic.ttf");
break;
case ROBOTO_REGULAR:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
break;
case ROBOTO_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Italic.ttf");
break;
case ROBOTO_MEDIUM:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Medium.ttf");
break;
case ROBOTO_MEDIUM_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-MediumItalic.ttf");
break;
case ROBOTO_BOLD:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
break;
case ROBOTO_BOLD_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldItalic.ttf");
break;
case ROBOTO_BLACK:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Black.ttf");
break;
case ROBOTO_BLACK_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BlackItalic.ttf");
break;
case ROBOTO_CONDENSED:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Condensed.ttf");
break;
case ROBOTO_CONDENSED_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-CondensedItalic.ttf");
break;
case ROBOTO_CONDENSED_BOLD:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensed.ttf");
break;
case ROBOTO_CONDENSED_BOLD_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensedItalic.ttf");
break;
default:
throw new IllegalArgumentException("Unknown `typeface` attribute value " + typefaceValue);
}
return typeface;
}
}
Example of use:
<your.package.widget.RobotoTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:typeface="roboto_thin"
android:textSize="22sp"
android:text="Roboto Thin"/>
Resources:
Roboto & Noto fonts
It's too late but my it helps the other
i have created CustomTextView which has an attribute called typeFace and it's care of memory leak problem with typeface loading without caching
Firstly Fonts class which load the fonts from assets for one time only
import android.content.Context;
import android.graphics.Typeface;
import java.util.Hashtable;
/**
* Created by tonyhaddad on 7/19/15.
*/
public class Fonts {
private Context context;
public Fonts(Context context) {
this.context = context;
}
private static Hashtable<String, Typeface> sTypeFaces = new Hashtable<String, Typeface>(
4);
public static Typeface getTypeFace(Context context, String fileName) {
Typeface tempTypeface = sTypeFaces.get(fileName);
if (tempTypeface == null) {
String fontPath=null;
if(fileName=="metabold")
fontPath ="fonts/Meta-Bold.ttf";
else if(fileName=="metanormal")
fontPath="fonts/Meta-Normal.ttf";
else if(fileName=="gsligh")
fontPath="fonts/gesslight.ttf";
else if(fileName=="bold")
fontPath="fonts/Lato-Bold.ttf";
else if(fileName=="rcr")
fontPath="fonts/RobotoCondensed-Regular.ttf";
else if(fileName=="mpr")
fontPath="fonts/MyriadPro-Regular.otf";
else if(fileName=="rr")
fontPath="fonts/Roboto-Regular.ttf";
tempTypeface = Typeface.createFromAsset(context.getAssets(), fontPath);
sTypeFaces.put(fileName, tempTypeface);
}
return tempTypeface;
}
}
then you need to add a custom attribute in the attrs.xml add this
<declare-styleable name="CustomFontTextView">
<attr name="typeFace" format="string" />
</declare-styleable>
then custom class
package package_name;
/**
* Created by tonyhaddad on 8/26/15.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
import package_name.R;
public class CustomFontTextView extends TextView {
String typeFace;
public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) {
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomFontTextView,
0, 0);
try {
typeFace = a.getString(0);
} finally {
a.recycle();
}
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
public CustomFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (isInEditMode()) {
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomFontTextView,
0, 0);
try {
typeFace = a.getString(0);
} finally {
a.recycle();
}
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
public CustomFontTextView(Context context) {
super(context);
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
private void init() {
}
public String getTypeFace() {
return typeFace;
}
public void setTypeFace(String typeFace) {
this.typeFace = typeFace;
invalidate();
requestLayout();
}
}
and finally add the text view
<package_name.CustomFontTextView
xmlns:custom="http://schemas.android.com/apk/res-auto/package_name"
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="41dp"
android:gravity="center_vertical"
android:text="text"
android:textColor="#000"
android:textSize="23sp"
custom:typeFace="metanormal"/>
and you can change the font progrmaticlly with setTypeFace method
also you can move the custom namespace to your parent layout if you want to use more than one from this view
Happy Coding :)
The method below, called in onCreate() and passed your outermost ViewGroup, will work for everything but text that is dynamically created (ie dynamic lists, alerts, etc.). An easy way to get the outermost ViewGroup is to use getRootView on any one of your views.
public void onCreate(Bundle savedInstanceState){
//onCreate code...
EditText text = (EditText) findViewById(R.id.editText1);
setTypeFaceForViewGroup((ViewGroup) text.getRootView());
}
private void setTypeFaceForViewGroup(ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++) {
if (vg.getChildAt(i) instanceof ViewGroup)
setTypeFaceForViewGroup((ViewGroup) vg.getChildAt(i));
else if (vg.getChildAt(i) instanceof TextView)
((TextView) vg.getChildAt(i)).setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Your_Font.ttf"));
}
}
This should work for dynamic content as well, you'd just have to call it, passing in whatever you created, just after you created it (I haven't tested this, though).
To save memory, you'll probably want to make the typeface a static variable, rather than creating a new one each time the loop runs like I have here.
If you are looking for a more general programatic solution, I created a static class that can be used to set the Typeface of an entire view (Activity UI). Note that I am working with Mono (C#) but you can implement it easily using Java.
You can pass this class a layout or a specific view that you want to customize. If you want to be super efficient you could implement it using the Singleton pattern.
public static class AndroidTypefaceUtility
{
static AndroidTypefaceUtility()
{
}
//Refer to the code block beneath this one, to see how to create a typeface.
public static void SetTypefaceOfView(View view, Typeface customTypeface)
{
if (customTypeface != null && view != null)
{
try
{
if (view is TextView)
(view as TextView).Typeface = customTypeface;
else if (view is Button)
(view as Button).Typeface = customTypeface;
else if (view is EditText)
(view as EditText).Typeface = customTypeface;
else if (view is ViewGroup)
SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
else
Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
}
catch (Exception ex)
{
Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
throw ex;
}
}
else
{
Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
}
}
public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
{
if (customTypeface != null && layout != null)
{
for (int i = 0; i < layout.ChildCount; i++)
{
SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
}
}
else
{
Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
}
}
}
In your activity you will need to create a Typeface object. I create mine in the OnCreate() using a .ttf file placed in my Resources/Assets/ directory. Make sure that the file is marked as an Android Asset in its' properties.
protected override void OnCreate(Bundle bundle)
{
...
LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
}
Unfortunately, Android doesn't provide the quick, easy and clean way you're looking for to change the font for your entire app. But recently I've looked into this matter and created some tools that allow you to change the font without any coding (you can do it all through xml, styles and even text appearances). They're based on similar solutions like you see in the other answers here, but allow for far more flexibility. You can read all about it on this blog, and see the github project here.
Here's an example of how to apply these tools. Put all your font files in assets/fonts/. Then, declare those fonts in an xml file (e.g. res/xml/fonts.xml) and load this file early in your app with TypefaceManager.initialize(this, R.xml.fonts); (e.g., in the onCreate of your Application class). The xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<familyset>
<!-- Some Font. Can be referenced with 'someFont' or 'aspergit' -->
<family>
<nameset>
<name>aspergit</name>
<name>someFont</name>
</nameset>
<fileset>
<file>Aspergit.ttf</file>
<file>Aspergit Bold.ttf</file>
<file>Aspergit Italic.ttf</file>
<file>Aspergit Bold Italic.ttf</file>
</fileset>
</family>
<!-- Another Font. Can be referenced with 'anotherFont' or 'bodoni' -->
<family>
<nameset>
<name>bodoni</name>
<name>anotherFont</name>
</nameset>
<fileset>
<file>BodoniFLF-Roman.ttf</file>
<file>BodoniFLF-Bold.ttf</file>
</fileset>
</family>
</familyset>
Now you can use these fonts in your style or xml (provided you use the tools I mentioned above), by using the custom UI element com.innovattic.font.FontTextView in your xml layout. Below you can see how you can apply a font to all texts in your entire app, just by editing res/values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<!-- Application theme -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:textViewStyle">#style/MyTextViewStyle</item>
</style>
<!-- Style to use for ALL text views (including FontTextView) -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="MyTextViewStyle" parent="#android:style/Widget.Holo.Light.TextView">
<item name="android:textAppearance">#style/MyTextAppearance</item>
</style>
<!-- Text appearance to use for ALL text views (including FontTextView) -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="MyTextAppearance" parent="#android:style/TextAppearance.Holo">
<!-- Alternatively, reference this font with the name "aspergit" -->
<!-- Note that only our own TextView's will use the font attribute -->
<item name="flFont">someFont</item>
<item name="android:textStyle">bold|italic</item>
</style>
<!-- Alternative style, maybe for some other widget -->
<style name="StylishFont">
<item name="flFont">anotherFont</item>
<item name="android:textStyle">normal</item>
</style>
</resources>
With the accompanying res/layout/layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!-- This text view is styled with the app theme -->
<com.innovattic.font.FontTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This uses my font in bold italic style" />
<!-- This text view is styled here and overrides the app theme -->
<com.innovattic.font.FontTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:flFont="anotherFont"
android:textStyle="normal"
android:text="This uses another font in normal style" />
<!-- This text view is styled with a style and overrides the app theme -->
<com.innovattic.font.FontTextView
style="#style/StylishFont"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This also uses another font in normal style" />
</LinearLayout>
Don't forget to apply the theme in your Android manifest.
I would like to add a note to the great solution of leocadiotine. It is perfect, but when using this Custom TextView many time slows down the application, since it has to access the assets every time a textview is created. I suggest to use something like the View Holder pattern in the Adapters, i wrote an example:
public class Fonts {
private static final Map<String, Typeface> typefaces = new HashMap<String, Typeface>();
public static Typeface getTypeface(Context ctx, String fontName) {
Typeface typeface = typefaces.get(fontName);
if (typeface == null) {
typeface = Typeface.createFromAsset(ctx.getAssets(), fontName);
typefaces.put(fontName, typeface);
}
return typeface;
}
}
In this way the application access the assets only one time per asset, and it keeps them in memory for further needs.
I don't know if it changes the whole app, but I have managed to change some components that couldn't otherwise be changed by doing this:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Lucida Sans Unicode.ttf");
Typeface.class.getField("DEFAULT").setAccessible(true);
Typeface.class.getField("DEFAULT_BOLD").setAccessible(true);
Typeface.class.getField("DEFAULT").set(null, tf);
Typeface.class.getField("DEFAULT_BOLD").set(null, tf);
I have found step by step information at this link,link: https://github.com/jaydipumaretiya/CustomTypeface/
There are many ways to use typeface correctly in android, you have to put your typeface file in
assets folder under your main directly and can use it run-time.
Other simplest way is use default library to set typeface in your xml file.
I have prefer this custom typeface library to set typeface to TextView, EditText, Button, CheckBox,
RadioButton and AutoCompleteTextView and other wedget in android.
Android 8.0 (API level 26) introduces a new feature, Fonts in XML.You can create a fontfamily file and set it in styles.xml.
To add fonts as resources, perform the following steps in the Android
Studio:
1.Right-click the res folder and go to New > Android resource directory. The New Resource Directory window appears.
2.In the Resource type list, select font, and then click OK. Note: The name of the resource directory must be font.
3.Add your font files in the font folder.
To create a font family, perform the following steps :
1.Right-click the font folder and go to New > Font resource file. The New Resource File window appears.
2.Enter the file name, and then click OK. The new font resource XML opens in the editor.
3.Enclose each font file, style, and weight attribute in the element. The following XML illustrates adding font-related attributes
in the font resource XML:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="#font/lobster_regular" />
<font
android:fontStyle="italic"
android:fontWeight="400"
android:font="#font/lobster_italic" />
</font-family>
Adding fonts to style
Open the styles.xml, and set the fontFamily attribute to the font file
you want to access.
<style name="customfontstyle" parent="#android:style/TextAppearance.Small">
<item name="android:fontFamily">#font/lobster</item>
</style>
Source:Fonts in XML
To use external fonts, first download the font in .tff format
Google font- Roboto
Add the font asset folder as shown in the image below
After the font asset folder is created, copy and paste the downloaded .tff font into the "font" folder. (make sure the name is formatted well. )
Reference the font in your theme.xml or any layout using the android:fontFamily="#font/splashfont" property.
If you want the font to apply to the entire application, set the fontfamily in you theme.xml. This is how you do it in a theme.xml file
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.FishPott" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#color/color_black_level_1</item>
<item name="colorPrimaryVariant">#color/color_black_level_2</item>
<item name="colorOnPrimary">#color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">#color/color_black_level_1</item>
<item name="colorSecondaryVariant">#color/color_black_level_2</item>
<item name="colorOnSecondary">#color/color_white_level_1</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
<item name="android:fontFamily">#font/robotoregular</item>
</style>
I am trying to do a application-wide font change and creating a style file to do so. In this file (below) I just want to change typeface value of TextAppearance style of Android.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="NightRiderFont" parent="#android:style/TextAppearance">
<item name="android:typeface"> /***help need here***/ </item>
</style>
</resources>
However font is in "assets/fonts/". How can I access this font, so I can use that style as a theme to get rid of changing all TextViews by hand programatically.
As summary: How can I access 'a file from assets folder' in XML?
In my research, there is no way to add external font to the xml file. Only the 3 default font is available in xml
But you can use in java using this code.
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/verdana.ttf");
textfield.setTypeface(tf,Typeface.BOLD);
Update:
Now I find a way to do this by creating a custom class extending the TextView and use that in the xml file.
public class TextViewWithFont extends TextView {
private int defaultDimension = 0;
private int TYPE_BOLD = 1;
private int TYPE_ITALIC = 2;
private int FONT_ARIAL = 1;
private int FONT_OPEN_SANS = 2;
private int fontType;
private int fontName;
public TextViewWithFont(Context context) {
super(context);
init(null, 0);
}
public TextViewWithFont(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
// Load attributes
final TypedArray a = getContext().obtainStyledAttributes(
attrs, R.styleable.font, defStyle, 0);
fontName = a.getInt(R.styleable.font_name, defaultDimension);
fontType = a.getInt(R.styleable.font_type, defaultDimension);
a.recycle();
MyApplication application = (MyApplication ) getContext().getApplicationContext();
if (fontName == FONT_ARIAL) {
setFontType(application .getArialFont());
} else if (fontName == FONT_OPEN_SANS) {
setFontType(application .getOpenSans());
}
}
private void setFontType(Typeface font) {
if (fontType == TYPE_BOLD) {
setTypeface(font, Typeface.BOLD);
} else if (fontType == TYPE_ITALIC) {
setTypeface(font, Typeface.ITALIC);
} else {
setTypeface(font);
}
}
}
and in xml
<com.example.customwidgets.TextViewWithFont
font:name="Arial"
font:type="bold"
android:layout_width="wrap_content"
android:text="Hello world "
android:padding="5dp"
android:layout_height="wrap_content"/>
dont forget to add the schema in root of your xml
xmlns:font="http://schemas.android.com/apk/res-auto"
And create an attrs.xml file inside values directory, which is holding our custom attribues:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="font">
<attr name="type">
<enum name="bold" value="1"/>
<enum name="italic" value="2"/>
</attr>
<attr name="name">
<enum name="Arial" value="1"/>
<enum name="OpenSans" value="2"/>
</attr>
</declare-styleable>
</resources>
Update:
Found some performance issue when this custom view is used in
listview, that is because the font Object is creating every time the
view is loaded. Solution I found is to initialize the font in Application
Class and refer that font object by
MyApplication application = (MyApplication) getContext().getApplicationContext();
Application class will look like this
public class MyApplication extends Application {
private Typeface arialFont, openSans;
public void onCreate() {
super.onCreate();
arialFont = Typeface.createFromAsset(getAssets(), QRUtils.FONT_ARIAL);
openSans = Typeface.createFromAsset(getAssets(), QRUtils.FONT_OPEN_SANS);
}
public Typeface getArialFont() {
return arialFont;
}
public Typeface getOpenSans() {
return openSans;
}
}
Edit 2:
Finally fonts are supported by xml (also backwards compatible via support library): https://developer.android.com/preview/features/fonts-in-xml.html
Edit:
I now use the Calligraphy library . It is the easiest way for custom fonts.
What can you do:
Custom font in a TextView
Custom font in TextAppearance
Custom font in Styles
Custom font in Themes
FontSpannable to only apply font to a part of the text
I found another way to do this.
You have to make your own TextView using this tutorial
It is not that difficult and after this you can just use that TextView with your own font.
I don't know if anybody still watches this, but I thought it might help.
Uses this function if you are using single font.
public static void applyFont(final Context context, final View root, final String fontName) {
try {
if (root instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) root;
for (int i = 0; i < viewGroup.getChildCount(); i++)
applyFont(context, viewGroup.getChildAt(i), fontName);
} else if (root instanceof TextView)
((TextView) root).setTypeface(Typeface.createFromAsset(context.getAssets(), fontName));
} catch (Exception e) {
Log.e("ProjectName", String.format("Error occured when trying to apply %s font for %s view", fontName, root));
e.printStackTrace();
}
}
Soorya is right, but if you have to put the same font on many textViews, I recommend you to put that code inside a static method that return the Typeface wanted. It will reduce lines in your code. Or even better create a class that extends Application and make a GET method that return the Typeface. That method will be reachable from any Activity inside your application (without the need of using static variables or static methods).
Check this out with the help of this don't need to set custom font programmatically.
https://stackoverflow.com/a/27588966/4331353
fount change is very basic functionality in android which is mostly needed to each and every application.so every one want to change only once in application that reduce our development time so i would suggest you to see this link
FountChanger.class.
You Have just make Public calls And attached Method like this
public class TextViewFontType {
public Typeface typeface;
public void fontTextView(final TextView textView, final String fonttype) {
typeface = Typeface.createFromAsset(textView.getContext().getAssets(), fonttype);
textView.setTypeface(typeface);
}
have you use any where method TextView set font-family.
public class FontList {
public static final String gothicbNormal="fonts/gothicb.ttf";
public static final String gothicbBold="fonts/gothicb.ttf";
}
made FontList calss after you have just call methods any where with pass two parameter.
I took droid kid's answer and made it work with ANY font, just by typing the font filename directly into the XML:
layout.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto" >
<!-- where font file is at "assets/fonts/arial.ttf" -->
<com.odbol.widgets.TextViewWithFont
...
custom:fontFilePath="fonts/arial.ttf" />
</RelativeLayout>
Fonts.java
public class Fonts {
// use Weak so fonts are freed from memory when you stop using them
private final static Map<String, Typeface> fonts = new WeakHashMap<>(5);
/***
* Returns a font at the given path within the assets directory.
*
* Caches fonts to save resources.
*
* #param context
* #param fontPath Path to a font file relative to the assets directory, e.g. "fonts/Arial.ttf"
* #return
*/
public synchronized static Typeface getFont(Context context, String fontPath) {
Typeface font = fonts.get(fontPath);
if (font == null) {
font = Typeface.createFromAsset(context.getAssets(), fontPath);
fonts.put(fontPath, font);
}
return font;
}
}
values/attrs.xml
<resources>
<declare-styleable name="TextViewWithFont">
<!-- a path to a font, relative to the assets directory -->
<attr name="fontFilePath" format="string" />
<attr name="type">
<enum name="bold" value="1"/>
<enum name="italic" value="2"/>
</attr>
</declare-styleable>
</resources>
TextViewWithFont.java
public class TextViewWithFont extends TextView {
private int defaultDimension = 0;
private int TYPE_BOLD = 1;
private int TYPE_ITALIC = 2;
private int fontType;
private int fontName;
public TextViewWithFont(Context context) {
super(context);
init(null, 0);
}
public TextViewWithFont(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
// Load attributes
final TypedArray a = getContext().obtainStyledAttributes(
attrs, R.styleable.TextViewWithFont, defStyle, 0);
String fontPath = a.getString(R.styleable.TextViewWithFont_fontFilePath);
fontType = a.getInt(R.styleable.TextViewWithFont_type, defaultDimension);
a.recycle();
if (fontPath != null) {
setFontType(Fonts.getFont(getContext(), fontPath));
}
}
private void setFontType(Typeface font) {
if (fontType == TYPE_BOLD) {
setTypeface(font, Typeface.BOLD);
} else if (fontType == TYPE_ITALIC) {
setTypeface(font, Typeface.ITALIC);
} else {
setTypeface(font);
}
}
}
hope use full to you:-
TextView text = (TextView) findViewById(R.id.custom_font);
Typeface font = Typeface.createFromAsset(getAssets(), "yourfont.ttf");
text.setTypeface(font);
Instead of assets folder, you can put the .ttf file on fonts folder.
To use fonts support in XML feature on devices running Android 4.1 (API level 16) and higher, use the Support Library 26+.
Right click res folder, new -> Android resource directory-> select font -> Ok.
put your "myfont.ttf" file in newly created font folder.
On res/values/styles.xml
add,
<style name="customfontstyle" parent="#android:style/TextAppearance.Small">
<item name="android:fontFamily">#font/myfont</item>
</style>
On layout file add android:textAppearance="#style/customfontstyle",
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/customfontstyle"/>
Refer : https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml
//accessing font file in code,
Typeface type = Typeface.createFromAsset(getResources().getAssets(),"fonts/arial.ttf");
textView.setTypeface(type);//assign typeface to textview
//in assets folder->fonts(foldername)->arial.ttf(font file name)
You can use this library: https://github.com/InflationX/Calligraphy
You only have to add the font you want to use on your layout.
Like this:
<TextView
fontPath="fonts/verdana.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
1.Fisrt we can add assets folder> in that your font styles.ttfs in your app then
2.write access code for fonts in strings like :
<string name="fontregular">OpenSans-Light.ttf</string>
<string name="fontmedium">OpenSans-Regular.ttf</string>
3.Accessing some layout xml file textview code like this below:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#string/fontregular"
android:textColor="#color/normalfont"
android:textSize="#dimen/textregular"/>
4.Add dimensions for font size :
<dimen name="textregular">14sp</dimen>
<dimen name="textheader">16sp</dimen>
<dimen name="smalltext">12sp</dimen>
<dimen name="littletext">10sp</dimen>
<dimen name="hightfont">18sp</dimen>
5.Add font color in colors :
<color name="normalfont">#666</color>
<color name="headerfont">#333</color>
<color name="aquablue">#4da8e3</color>
<color name="orange">#e96125</color>
6.Then apply changes it is easy process to change hole app.
Happy coding keep smile..
You can access your font file from assets folder to xml file.
android:fontFamily="fonts/roboto_regular.ttf"
fonts is the sub folder in assets folder.
How to change the font in a TextView, as default it's shown up as Arial? How to change it to Helvetica?
First, the default is not Arial. The default is Droid Sans.
Second, to change to a different built-in font, use android:typeface in layout XML or setTypeface() in Java.
Third, there is no Helvetica font in Android. The built-in choices are Droid Sans (sans), Droid Sans Mono (monospace), and Droid Serif (serif). While you can bundle your own fonts with your application and use them via setTypeface(), bear in mind that font files are big and, in some cases, require licensing agreements (e.g., Helvetica, a Linotype font).
EDIT
The Android design language relies on traditional typographic tools
such as scale, space, rhythm, and alignment with an underlying grid.
Successful deployment of these tools is essential to help users
quickly understand a screen of information. To support such use of
typography, Ice Cream Sandwich introduced a new type family named
Roboto, created specifically for the requirements of UI and
high-resolution screens.
The current TextView framework offers Roboto in thin, light, regular
and bold weights, along with an italic style for each weight. The
framework also offers the Roboto Condensed variant in regular and bold
weights, along with an italic style for each weight.
After ICS, android includes Roboto fonts style,
Read more Roboto
EDIT 2
With the advent of Support Library 26, Android now supports custom fonts by
default. You can insert new fonts in res/fonts which can be set to TextViews individually either in XML or programmatically. The default font for the whole application can also be changed by defining it styles.xml The android developer documentation has a clear guide on this here
First download the .ttf file of the font you need (arial.ttf). Place it in the assets folder. (Inside assets folder create new folder named fonts and place it inside it.) Use the following code to apply the font to your TextView:
Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf");
textView.setTypeface(type);
Typeface tf = Typeface.createFromAsset(getAssets(),
"fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);
You might want to create static class which will contain all the fonts. That way, you won't create the font multiple times which might impact badly on performance.
Just make sure that you create a sub-folder called "fonts" under "assets" folder.
Do something like:
public class CustomFontsLoader {
public static final int FONT_NAME_1 = 0;
public static final int FONT_NAME_2 = 1;
public static final int FONT_NAME_3 = 2;
private static final int NUM_OF_CUSTOM_FONTS = 3;
private static boolean fontsLoaded = false;
private static Typeface[] fonts = new Typeface[3];
private static String[] fontPath = {
"fonts/FONT_NAME_1.ttf",
"fonts/FONT_NAME_2.ttf",
"fonts/FONT_NAME_3.ttf"
};
/**
* Returns a loaded custom font based on it's identifier.
*
* #param context - the current context
* #param fontIdentifier = the identifier of the requested font
*
* #return Typeface object of the requested font.
*/
public static Typeface getTypeface(Context context, int fontIdentifier) {
if (!fontsLoaded) {
loadFonts(context);
}
return fonts[fontIdentifier];
}
private static void loadFonts(Context context) {
for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
}
fontsLoaded = true;
}
}
This way, you can get the font from everywhere in your application.
Best practice ever
TextViewPlus.java:
public class TextViewPlus extends TextView {
private static final String TAG = "TextView";
public TextViewPlus(Context context) {
super(context);
}
public TextViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
String customFont = a.getString(R.styleable.TextViewPlus_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
public boolean setCustomFont(Context ctx, String asset) {
Typeface typeface = null;
try {
typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
} catch (Exception e) {
Log.e(TAG, "Unable to load typeface: "+e.getMessage());
return false;
}
setTypeface(typeface);
return true;
}
}
attrs.xml: (Where to place res/values)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextViewPlus">
<attr name="customFont" format="string"/>
</declare-styleable>
</resources>
How to use:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.mypackage.TextViewPlus
android:id="#+id/textViewPlus1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:text="#string/showingOffTheNewTypeface"
foo:customFont="my_font_name_regular.otf">
</com.mypackage.TextViewPlus>
</LinearLayout>
Hope this will help you.
The answers above are correct. Just make sure that you create a sub-folder called "fonts" under "assets" folder if you are using that piece of code.
Another way to consolidate font creation...
public class Font {
public static final Font PROXIMA_NOVA = new Font("ProximaNovaRegular.otf");
public static final Font FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
private final String assetName;
private volatile Typeface typeface;
private Font(String assetName) {
this.assetName = assetName;
}
public void apply(Context context, TextView textView) {
if (typeface == null) {
synchronized (this) {
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), assetName);
}
}
}
textView.setTypeface(typeface);
}
}
And then to use in your activity...
myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);
Mind you, this double-checked locking idiom with the volatile field only works correctly with the memory model used in Java 1.5+.
Best practice is to use Android Support Library version 26.0.0 or above.
STEP 1: add font file
In res folder create new font resource dictionary
Add font file (.ttf, .orf)
For example, when font file will be helvetica_neue.ttf that will generates R.font.helvetica_neue
STEP 2: create font family
In font folder add new resource file
Enclose each font file, style, and weight attribute in the element.
For example:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="#font/helvetica_neue" />
</font-family>
STEP 3: use it
In xml layouts:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/my_font"/>
Or add fonts to style:
<style name="customfontstyle" parent="#android:style/TextAppearance.Small">
<item name="android:fontFamily">#font/lobster</item>
</style>
For more examples you can follow documentation:
Working with fonts
When your font is stored inside res/asset/fonts/Helvetica.ttf use the following:
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf");
txt.setTypeface(tf);
Or, if your font file is stores inside res/font/helvetica.ttf use the following:
Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);
It's a little old, but I improved the class CustomFontLoader a little bit and I wanted to share it so it can be helpfull. Just create a new class with this code.
import android.content.Context;
import android.graphics.Typeface;
public enum FontLoader {
ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");
private final String name;
private Typeface typeFace;
private FontLoader(final String name) {
this.name = name;
typeFace=null;
}
public static Typeface getTypeFace(Context context,String name){
try {
FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
if(item.typeFace==null){
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}
return item.typeFace;
} catch (Exception e) {
return null;
}
}
public static Typeface getTypeFace(Context context,int id){
FontLoader myArray[]= FontLoader.values();
if(!(id<myArray.length)){
return null;
}
try {
if(myArray[id].typeFace==null){
myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");
}
return myArray[id].typeFace;
}catch (Exception e) {
return null;
}
}
public static Typeface getTypeFaceByName(Context context,String name){
for(FontLoader item: FontLoader.values()){
if(name.equalsIgnoreCase(item.name)){
if(item.typeFace==null){
try{
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}catch (Exception e) {
return null;
}
}
return item.typeFace;
}
}
return null;
}
public static void loadAllFonts(Context context){
for(FontLoader item: FontLoader.values()){
if(item.typeFace==null){
try{
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}catch (Exception e) {
item.typeFace=null;
}
}
}
}
}
Then just use this code on you textview:
Typeface typeFace=FontLoader.getTypeFace(context,"arial");
if(typeFace!=null) myTextView.setTypeface(typeFace);
I finally got a very easy solution to this.
use these Support libraries in app level gradle,
compile 'com.android.support:appcompat-v7:26.0.2'
compile 'com.android.support:support-v4:26.0.2'
then create a directory named "font" inside the res folder
put fonts(ttf) files in that font directory, keep in mind the naming conventions [e.g.name should not contain any special character, any uppercase character and any space or tab]
After that, reference that font from xml like this
<Button
android:id="#+id/btn_choose_employee"
android:layout_width="140dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:background="#drawable/rounded_red_btn"
android:onClick="btnEmployeeClickedAction"
android:text="#string/searching_jobs"
android:textAllCaps="false"
android:textColor="#color/white"
android:fontFamily="#font/times_new_roman_test"
/>
In this example, times_new_roman_test is a font ttf file from that font directory
import java.lang.ref.WeakReference;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Typeface;
public class FontsManager {
private static FontsManager instance;
private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();
private static Context context;
private FontsManager(final Context ctx) {
if (context == null) {
context = ctx;
}
}
public static FontsManager getInstance(final Context appContext) {
if (instance == null) {
instance = new FontsManager(appContext);
}
return instance;
}
public static FontsManager getInstance() {
if (instance == null) {
throw new RuntimeException(
"Call getInstance(Context context) at least once to init the singleton properly");
}
return instance;
}
public Typeface getFont(final String assetName) {
final WeakReference<Typeface> tfReference = typefaces.get(assetName);
if (tfReference == null || tfReference.get() == null) {
final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
assetName);
typefaces.put(assetName, new WeakReference<Typeface>(tf));
return tf;
}
return tfReference.get();
}
}
This way, you can create a View which inherits from TextView and calls setTypeface on its constructor.
get font from asset and set to all children
public static void overrideFonts(final Context context, final View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
overrideFonts(context, child);
}
} else if (v instanceof TextView ) {
((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
}
} catch (Exception e) {
}
}
add class FontTextView.java:
public class FontTextView extends TextView {
String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
init(attrs);
}
}
public FontTextView(Context context) {
super(context);
if (!isInEditMode()) {
init(null);
}
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
if (a.getString(R.styleable.FontTextView_font_type) != null) {
String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];
if (fontName != null) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
setTypeface(myTypeface);
}
a.recycle();
}
}
}
}
add to assets library font
add to attrs.xml ,
The numbers should be in the order in array class.
<declare-styleable name="FontTextView">
<attr name="font_type" format="enum">
<enum name="HelveticaNeue" value="0"/>
<enum name="HelveticaNeueLight" value="1"/>
<enum name="motschcc" value="2"/>
<enum name="symbol" value="3"/>
</attr>
Select a font from the list
Android uses the Roboto font, which is a really nice looking font, with several different weights (regular, light, thin, condensed) that look great on high density screens.
Check below link to check roboto fonts:
How to use Roboto in xml layout
Back to your question, if you want to change the font for all of the TextView/Button in your app, try adding below code into your styles.xml to use Roboto-light font:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
......
<item name="android:buttonStyle">#style/MyButton</item>
<item name="android:textViewStyle">#style/MyTextView</item>
</style>
<style name="MyButton" parent="#style/Widget.AppCompat.Button">
<item name="android:textAllCaps">false</item>
<item name="android:fontFamily">sans-serif-light</item>
</style>
<style name="MyTextView" parent="#style/TextAppearance.AppCompat">
<item name="android:fontFamily">sans-serif-light</item>
</style>
And don't forget to use 'AppTheme' in your AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
......
</application>
Maybe something a bit simpler:
public class Fonts {
public static HashSet<String,Typeface> fonts = new HashSet<>();
public static Typeface get(Context context, String file) {
if (! fonts.contains(file)) {
synchronized (this) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
fonts.put(name, typeface);
}
}
return fonts.get(file);
}
}
// Usage
Typeface myFont = Fonts.get("arial.ttf");
(Note this code is untested, but in general this approach should work well.)