How to Set a Custom Font in the ActionBar Title?
How (if possible) could I set a custom font in a ActionBar title text(only - not the tab text) with a font in my assets folder? I don't want to use the android:logo option.
You can do this using a custom TypefaceSpan
class. It's superior to the customView
approach indicated above because it doesn't break when using other Action Bar elements like expanding action views.
The use of such a class would look something like this:
SpannableString s = new SpannableString("My Title");
s.setSpan(new TypefaceSpan(this, "MyTypeface.otf"), 0, s.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Update the action bar title with the TypefaceSpan instance
ActionBar actionBar = getActionBar();
actionBar.setTitle(s);
The custom TypefaceSpan
class is passed your Activity context and the name of a typeface in your assets/fonts
directory. It loads the file and caches a new Typeface
instance in memory. The complete implementation of TypefaceSpan
is surprisingly simple:
/**
* Style a {@link Spannable} with a custom {@link Typeface}.
*
* @author Tristan Waddington
*/
public class TypefaceSpan extends MetricAffectingSpan {
/** An <code>LruCache</code> for previously loaded typefaces. */
private static LruCache<String, Typeface> sTypefaceCache =
new LruCache<String, Typeface>(12);
private Typeface mTypeface;
/**
* Load the {@link Typeface} and apply to a {@link Spannable}.
*/
public TypefaceSpan(Context context, String typefaceName) {
mTypeface = sTypefaceCache.get(typefaceName);
if (mTypeface == null) {
mTypeface = Typeface.createFromAsset(context.getApplicationContext()
.getAssets(), String.format("fonts/%s", typefaceName));
// Cache the loaded Typeface
sTypefaceCache.put(typefaceName, mTypeface);
}
}
@Override
public void updateMeasureState(TextPaint p) {
p.setTypeface(mTypeface);
// Note: This flag is required for proper typeface rendering
p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setTypeface(mTypeface);
// Note: This flag is required for proper typeface rendering
tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
}
Simply copy the above class into your project and implement it in your activity's onCreate
method as shown above.
I agree that this isn't completely supported, but here's what I did. You can use a custom view for your action bar (it will display between your icon and your action items). I'm using a custom view and I have the native title disabled. All of my activities inherit from a single activity, which has this code in onCreate:
this.getActionBar().setDisplayShowCustomEnabled(true);
this.getActionBar().setDisplayShowTitleEnabled(false);
LayoutInflater inflator = LayoutInflater.from(this);
View v = inflator.inflate(R.layout.titleview, null);
//if you need to customize anything else about the text, do it here.
//I'm using a custom TextView with a custom font in my layout xml so all I need to do is set title
((TextView)v.findViewById(R.id.title)).setText(this.getTitle());
//assign the view to the actionbar
this.getActionBar().setCustomView(v);
And my layout xml (R.layout.titleview in the code above) looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" >
<com.your.package.CustomTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textSize="20dp"
android:maxLines="1"
android:ellipsize="end"
android:text="" />
</RelativeLayout>
int titleId = getResources().getIdentifier("action_bar_title", "id",
"android");
TextView yourTextView = (TextView) findViewById(titleId);
yourTextView.setTextColor(getResources().getColor(R.color.black));
yourTextView.setTypeface(face);
From Android Support Library v26 + Android Studio 3.0 onwards, this process has become easy as a flick!!
Follow these steps to change the font of Toolbar Title:
- Read Downloadable Fonts & select any font from the list (my recommendation) or load a custom font to
res > font
as per Fonts in XML -
In
res > values > styles
, paste the following (use your imagination here!)<style name="TitleBarTextAppearance" parent="android:TextAppearance"> <item name="android:fontFamily">@font/your_desired_font</item> <item name="android:textSize">23sp</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@android:color/white</item> </style>
-
Insert a new line in your Toolbar properties
app:titleTextAppearance="@style/TextAppearance.TabsFont"
as shown below<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:titleTextAppearance="@style/TitleBarTextAppearance" app:popupTheme="@style/AppTheme.PopupOverlay"/>
Enjoy Custom Actionbar Title font styling!!
The Calligraphy library let's you set a custom font through the app theme, which would also apply to the action bar.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item>
</style>
<style name="AppTheme.Widget"/>
<style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView">
<item name="fontPath">fonts/Roboto-ThinItalic.ttf</item>
</style>
All it takes to activate Calligraphy is attaching it to your Activity context:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}
The default custom attribute is fontPath
, but you may provide your own custom attribute for the path by initializing it in your Application class with CalligraphyConfig.Builder
. Usage of android:fontFamily
has been discouraged.