Android Custom Fonts - For System Components Like Actionbar, Toast, Dialogs
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:
- 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"