Skip to content Skip to sidebar Skip to footer

Android Custom Fonts - For System Components Like Actionbar, Toast, Dialogs

I am working on application translated to languages that are not supported - missing fonts on devices. So I added fonts to application and changed typeface for all TextViews, EditT

Solution 1:

Create Views with custom fonts like this

FontManager.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.content.res.XmlResourceParser;
import android.graphics.Typeface;
import android.view.InflateException;

publicclassFontManager
{
    //Making FontManager a singleton classprivatestaticclassInstanceHolder
    {
        privatestaticfinalFontManagerINSTANCE=newFontManager();
    }

    publicstatic FontManager getInstance()
    {
        return FontManager.InstanceHolder.INSTANCE;
    }

    privateFontManager()
    {
    }

    // Different tags used in XML file.privatestaticfinalStringTAG_FAMILY="family";
    privatestaticfinalStringTAG_NAMESET="nameset";
    privatestaticfinalStringTAG_NAME="name";
    privatestaticfinalStringTAG_FILESET="fileset";
    privatestaticfinalStringTAG_FILE="file";

    // Different styles supported.privatestaticfinalStringSTYLE_BOLD="-Bold.ttf";
    privatestaticfinalStringSTYLE_ITALIC="-Italic.ttf";
    privatestaticfinalStringSTYLE_BOLDITALIC="-BoldItalic.ttf";

    privateclassFontStyle
    {
        int style;
        Typeface font;
    }

    privateclassFont
    {
        // different font-family names that this Font will respond to.
        List<String> families;

        // different styles for this font.
        List<FontStyle> styles;
    }

    private List<Font> mFonts;

    //private boolean isFamilySet = false;privatebooleanisName=false;
    privatebooleanisFile=false;

    // Parse the resId and initialize the parser.publicvoidinitialize(Context context, int resId)
    {
        XmlResourceParserparser=null;
        try
        {
            parser = context.getResources().getXml(resId);
            mFonts = newArrayList<Font>();

            String tag;
            inteventType= parser.getEventType();

            Fontfont=null;

            do
            {
                tag = parser.getName();

                switch ( eventType )
                {
                    case XmlPullParser.START_TAG:
                        if ( tag.equals(TAG_FAMILY) )
                        {
                            // one of the font-families.
                            font = newFont();
                        }
                        elseif ( tag.equals(TAG_NAMESET) )
                        {
                            // a list of font-family names supported.
                            font.families = newArrayList<String>();
                        }
                        elseif ( tag.equals(TAG_NAME) )
                        {
                            isName = true;
                        }
                        elseif ( tag.equals(TAG_FILESET) )
                        {
                            // a list of files specifying the different styles.
                            font.styles = newArrayList<FontStyle>();
                        }
                        elseif ( tag.equals(TAG_FILE) )
                        {
                            isFile = true;
                        }
                        break;

                    case XmlPullParser.END_TAG:
                        if ( tag.equals(TAG_FAMILY) )
                        {
                            // add it to the list.if ( font != null )
                            {
                                mFonts.add(font);
                                font = null;
                            }
                        }
                        elseif ( tag.equals(TAG_NAME) )
                        {
                            isName = false;
                        }
                        elseif ( tag.equals(TAG_FILE) )
                        {
                            isFile = false;
                        }
                        break;

                    case XmlPullParser.TEXT:
                        Stringtext= parser.getText();
                        if ( isName )
                        {
                            // value is a name, add it to list of family-names.if ( font.families != null )
                                font.families.add(text);
                        }
                        elseif ( isFile )
                        {
                            // value is a file, add it to the proper kind.FontStylefontStyle=newFontStyle();
                            fontStyle.font = Typeface.createFromAsset(context.getAssets(), text);

                            if ( text.endsWith(STYLE_BOLD) )
                                fontStyle.style = Typeface.BOLD;
                            elseif ( text.endsWith(STYLE_ITALIC) )
                                fontStyle.style = Typeface.ITALIC;
                            elseif ( text.endsWith(STYLE_BOLDITALIC) )
                                fontStyle.style = Typeface.BOLD_ITALIC;
                            else
                                fontStyle.style = Typeface.NORMAL;

                            font.styles.add(fontStyle);
                        }
                }

                eventType = parser.next();

            }
            while ( eventType != XmlPullParser.END_DOCUMENT );

        }
        catch ( XmlPullParserException e )
        {
            thrownewInflateException("Error inflating font XML", e);
        }
        catch ( IOException e )
        {
            thrownewInflateException("Error inflating font XML", e);
        }
        finally
        {
            if ( parser != null )
                parser.close();
        }
    }

    public Typeface get(String family, int style)
    {
        for ( Font font : mFonts )
        {
            for ( String familyName : font.families )
            {
                if ( familyName.equals(family) )
                {
                    // if no style in specified, return normal style.if ( style == -1 )
                        style = Typeface.NORMAL;

                    for ( FontStyle fontStyle : font.styles )
                    {
                        if ( fontStyle.style == style )
                            return fontStyle.font;
                    }
                }
            }
        }

        returnnull;
    }
}

res/values/Fonts.xml

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleablename="Fonts"><!-- using android's --><attrname="android:textStyle" /><!-- our custom attribute --><attrname="font"format="string" /></declare-styleable></resources>

res/xml/fonts.xml

<?xml version="1.0" encoding="utf-8"?><familyset><!-- Arial --><family><nameset><name>Arial</name></nameset><fileset><file>fonts/Arial-Regular.ttf</file><file>fonts/Arial-Bold.ttf</file><file>fonts/Arial-Italic.ttf</file><file>fonts/Arial-BoldItalic.ttf</file></fileset></family></familyset>

Add the fonts inside assets/fonts

Arial-Bold.ttf
Arial-BoldItalic.ttf
Arial-Italic.ttf
Arial-Regular.ttf

Create your custom view Ex: FontableTextView.java

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextView;

publicclassFontableTextViewextendsTextView
{
    privatestaticfinalStringTAG="FontableTextView";

    publicFontableTextView(Context context)
    {
        super(context);
    }

    publicFontableTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    publicFontableTextView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    /* 
     * @see android.widget.CompoundButton#onDraw(android.graphics.Canvas)
     */@OverrideprotectedvoidonDraw(Canvas canvas)
    {
        super.onDraw(canvas);
    }

    privatevoidsetCustomFont(Context ctx, AttributeSet attrs)
    {
        // Fonts work as a combination of particular family and the style. TypedArraya= ctx.obtainStyledAttributes(attrs, R.styleable.Fonts);
        Stringfamily= a.getString(R.styleable.Fonts_font);
        intstyle= a.getInt(R.styleable.Fonts_android_textStyle, -1);
        a.recycle();
        // Set the typeface based on the family and the style combination.if ( family != null )
        {
            setTypeface(FontManager.getInstance().get(family, style));
        }
    }
}

Initiate FontManager to set custom fonts at the start of the MainActivity

FontManager.getInstance().initialize(getApplicationContext(), R.xml.fonts);

Use the custom view in Layout XML

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:custom="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent" ><com.package.FontableTextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:layout_marginTop="20dip"android:text="FontableTextView"android:textStyle="bold"custom:font="Arial" /></RelativeLayout>

Solution 2:

  1. for actionbar:

use actionbar sherlock (http://actionbarsherlock.com/) and customize its code:

in com.actionbarsherlock.app.Actionbar add these two abstract methods:

publicabstractvoidsetTitleTypeface(Typeface TF);
publicabstractvoidsetSubtitleTypeface(Typeface TF);

and override these methods in com.actionbarsherlock.internal.app.ActionBarImpl

@OverridepublicvoidsetTitleTypeface(Typeface TF) {
    mActionView.setTitleTypeface(TF);     }

@OverridepublicvoidsetSubtitleTypeface(Typeface TF) {
    mActionView.setSubtitleTypeface(TF);    }

and also in com.actionbarsherlock.internal.app.ActionBarWrapper like this

@Override
public void setTitleTypeface(Typeface TF) {}
@Override
public void setSubtitleTypeface(Typeface TF) {}

and finally in com.actionbarsherlock.internal.widget.ActionBarView add these methods:

publicvoidsetTitleTypeface(Typeface TF){
    mTitleView.setTypeface(TF);
}

publicvoidsetSubtitleTypeface(Typeface TF){
    mSubtitleView.setTypeface(TF);
}

and now use it in your SherlockActivity like this:

TypefaceTF= Typeface.createFromAsset(getApplication().getAssets(),
                "Arial.ttf");
    getSupportActionBar().setTitleTypeface(TF);

Make Sure there is no better way!!!

2. for dialogs, system settings,... u should change code like this!

Post a Comment for "Android Custom Fonts - For System Components Like Actionbar, Toast, Dialogs"