如果可能的话,我该如何在ActionBar标题文本(仅限标题文本,而不是选项卡文本)中使用位于assets文件夹中的字体设置自定义字体? 我不想使用android:logo选项。
如果可能的话,我该如何在ActionBar标题文本(仅限标题文本,而不是选项卡文本)中使用位于assets文件夹中的字体设置自定义字体? 我不想使用android:logo选项。
您可以使用自定义的TypefaceSpan
类来实现这一点。它比上述的customView
方法更优越,因为它在使用其他操作栏元素(如扩展操作视图)时不会出现问题。
使用这样的类可能看起来像这样:
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);
自定义的TypefaceSpan
类需要传入您的Activity上下文和assets/fonts
目录中字体的名称。它会加载文件并在内存中缓存一个新的Typeface
实例。 TypefaceSpan
的完整实现非常简单:
/**
* 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);
}
}
只需将上面的类复制到您的项目中,并按照上面所示在您的活动的onCreate
方法中实现它。
我同意这并不是完全支持的,但是这是我的做法。您可以为操作栏使用自定义视图(它将显示在您的图标和操作项之间)。我正在使用自定义视图,并已禁用原生标题。所有我的活动都继承自一个单一的活动,该活动在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);
我的布局xml文件(在上面的代码中为R.layout.titleview)如下所示:
<?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);
从Android Support Library v26 + Android Studio 3.0开始,这个过程变得轻而易举!
按照以下步骤更改工具栏标题的字体:
res > font
中加载自定义字体在res > values > styles
中,粘贴以下内容(在这里发挥你的想象力!)
<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>
按照下面所示,在您的工具栏属性中插入一行app:titleTextAppearance="@style/TextAppearance.TabsFont"
以换行。
<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"/>
享受自定义Actionbar标题字体样式!!
Calligraphy库可以通过应用程序主题设置自定义字体,这也适用于操作栏。
<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>
只需要将 Calligraphy 附加到您的 Activity 上下文即可激活:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}
默认的自定义属性是fontPath
,但您可以通过在应用程序类中使用CalligraphyConfig.Builder
来初始化自己的自定义属性路径。不建议使用android:fontFamily
。
ActionBar actionBar = getSupportActionBar();
TextView tv = new TextView(getApplicationContext());
Typeface typeface = ResourcesCompat.getFont(this, R.font.monotype_corsiva);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, // Width of TextView
RelativeLayout.LayoutParams.WRAP_CONTENT); // Height of TextView
tv.setLayoutParams(lp);
tv.setText("Your Text"); // ActionBar title text
tv.setTextSize(25);
tv.setTextColor(Color.WHITE);
tv.setTypeface(typeface, typeface.ITALIC);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(tv);
typeface.ITALIC
替换为 Typeface.ITALIC
即可消除静态成员警告。 - Zain这种方法很丑陋,但你可以像这样做(因为action_bar_title被隐藏了):
try {
Integer titleId = (Integer) Class.forName("com.android.internal.R$id")
.getField("action_bar_title").get(null);
TextView title = (TextView) getWindow().findViewById(titleId);
// check for null and manipulate the title as see fit
} catch (Exception e) {
Log.e(TAG, "Failed to obtain action bar title reference");
}
这段代码适用于Gingerbread版本之后的设备,但是也可以轻松地扩展到与ActionBar Sherlock一起使用。
P.S. 根据@pjv的评论,有一种更好的方法来查找ActionBar标题ID。
final int titleId =
Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
以下代码适用于所有版本。我已在安装Gingerbread和JellyBean的设备上进行了测试。
private void actionBarIdForAll()
{
int titleId = 0;
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
{
titleId = getResources().getIdentifier("action_bar_title", "id", "android");
}
else
{
// This is the id is from your app's generated R class when ActionBarActivity is used for SupportActionBar
titleId = R.id.action_bar_title;
}
if(titleId>0)
{
// Do whatever you want ? It will work for all the versions.
// 1. Customize your fonts
// 2. Infact, customize your whole title TextView
TextView titleView = (TextView)findViewById(titleId);
titleView.setText("RedoApp");
titleView.setTextColor(Color.CYAN);
}
}
使用支持库中的新工具栏,可以设计自己的操作栏或使用以下代码
膨胀TextView并不是一个好选择,尝试使用Spannable StringBuilder。
Typeface font2 = Typeface.createFromAsset(getAssets(), "fonts/<your font in assets folder>");
SpannableStringBuilder SS = new SpannableStringBuilder("MY Actionbar Tittle");
SS.setSpan (new CustomTypefaceSpan("", font2), 0, SS.length(),Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
actionBar.setTitle(ss);
复制下面的类
public class CustomTypefaceSpan extends TypefaceSpan{
private final Typeface newType;
public CustomTypefaceSpan(String family, Typeface type) {
super(family);
newType = type;
}
@Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType);
}
@Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}
paint.setTypeface(tf);
}
}
我刚在onCreate()函数中执行了以下操作:
TypefaceSpan typefaceSpan = new TypefaceSpan("font_to_be_used");
SpannableString str = new SpannableString("toolbar_text");
str.setSpan(typefaceSpan,0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
getSupportActionBar().setTitle(str);
我正在使用支持库,如果您没有使用它们,我猜您应该切换到getActionBar()而不是getSupportActionBar()。
在Android Studio 3中,您可以按照此说明https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html添加自定义字体,然后在“font_to_be_used”中使用您新添加的字体。
textAllCaps
属性为 true(例如通过主题设置),则自定义字体将不会出现。当我将此技术应用于操作栏选项卡时,这对我造成了问题。 - JamesString.format("fonts/%s", typefaceName)
。如果不遵循这个规则,您可能会遇到问题并收到此错误消息:java.lang.RuntimeException: Unable to start activity ComponentInfo{com.your.pckage}: java.lang.RuntimeException: native typeface cannot be made
。 - Dzhuneyt