ActionBar 选项卡标题中的自定义字体
我正在尝试在 ActionBar
选项卡的标题上设置自定义字体.
I'm trying to set a custom Typeface on my ActionBar
tabs' titles.
我看到更多的开发人员要求在 SO 上以适当的方式执行此操作(例如 如何自定义Action Bar标签的字体 & 我如何(如果可能)在选项卡文本的 ActionBar 中设置自定义字体,并在我的资产文件夹中设置字体?) 但没有答案.
I have seen more developers asking for a proper way to do this on SO (e.g. How to customize the font of Action Bar tabs & How (if possible) could I set a custom font in a ActionBar on tab text with a font in my assets folder?) but no answers.
到目前为止,我采用了两种方法:
So far, I've followed two approaches:
1) 第一个是启发这个 SO question 包括为每个标签添加自定义布局:
1) The first one was inspired by this SO question and consists of inflating a custom layout for each tab:
LayoutInflater inflater = LayoutInflater.from(this);
View customView = inflater.inflate(R.layout.tab_title, null); // a custom layout for the tab title, basically contains a textview...
TextView titleTV = (TextView) customView.findViewById(R.id.action_custom_title);
titleTV.setText(mSectionsPagerAdapter.getPageTitle(i));
titleTV.setGravity(Gravity.CENTER_VERTICAL);
titleTV.setTypeface(((MyApp) getApplicationContext()).getCustomTypeface());
// ...Here I could also add any other styling I wanted to...
actionBar.getTabAt(i).setCustomView(customView);
这看起来不是一个很好的方法,因为如果选项卡 + 操作在横向模式下不适合 ActionBar,则选项卡标题会显示在溢出列表(微调器/下拉菜单)中,但所选值显示为空.当您单击此列表的项目时,所有这些视图都会消失.这尤其令人讨厌,例如,当用户展开搜索操作视图时,会导致 android 将选项卡显示为下拉菜单.
This doesn't look like a very good approach because if the tabs + actions don't fit to the ActionBar in landscape mode, the tab titles are displayed in an overflow list (Spinner/Drop-down) but the selected value shows up as empty. And when you click on this list's item, then all of these views disappear. This is particularly annoying when, for example the user expands a search action view which causes android to show the tab as a Drop-down.
2) 我尝试了另一种方法,如 here 涉及使用 SpannableString
但字体不会更改为我的自定义字体.
2) I've tried another approach as presented here which involves using a SpannableString
but the font doesn't change to my custom one.
SpannableString s = new SpannableString(mSectionsPagerAdapter.getPageTitle(i));
s.setSpan(new TypefaceSpan(this, "FontName.ttf"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
actionBar.addTab(actionBar.newTab().setText(s).setTabListener(this));
可以在这里查看类TypefaceSpan.
Class TypefaceSpan can be seen here.
那么...
有谁知道使用/assets/fonts/..."中的字体设置 ActionBar
选项卡标题的正确方法?任何帮助将不胜感激.
Does anyone know a proper way of styling the ActionBar
tabs' titles with a Typeface from "/assets/fonts/..."? Any help would be greatly appreciated.
更多关于第二种方法.我使用的 TypefaceSpan 类实际上是 android.text.style.TypefaceSpan 由用户@twaddington 在这里展示:如何在ActionBar Title中设置自定义字体?
More on the second approach. The TypefaceSpan class I'm using is actually a fork of android.text.style.TypefaceSpan as presented by user @twaddington here: How to Set a Custom Font in the ActionBar Title?
编辑 2:
在上一个链接中,有一条评论指出:如果在底层 TextView 上将 textAllCaps 属性设置为 true(例如通过主题),那么自定义字体将不会出现.这对我来说是个问题当我将此技术应用于操作栏选项卡项时".
In the previous link, a comment stated: "if the textAllCaps attribute is set to true on the underlying TextView (e.g. via a theme), then the custom font won't appear. This was an issue for me when I applied this technique to the action bar tab items".
我已经改变了我的风格,将 textAllCaps 设置为 false,现在第二种方法似乎有效.我会测试一下并发布结果.
I have changed my style so that textAllCaps was set to false and now the second method seems to work. I'll test it a bit and post the results.
结论:
之前编辑中的解决方案似乎有效.
The solution in the previous edit seems to work.
将@CommonsWare 的答案标记为正确的相关性.
Marking @CommonsWare's answer as correct for its relevancy.
@PeteH 的 PS
我在 6 个月前问过这个问题,所以我不记得所有细节了.我相信对于这个应用程序,我最终采用了不同的导航方法.我现在可以在应用程序中找到的所有内容(关于滑动...)是一个 Activity
,其布局包含一个带有 PagerTabStrip
的 ViewPager
,我样式如下:
I asked this 6 months ago so I don't remember all the details. I believe that for this app I ended up following a different approach for navigation. All I can find now in the app (regarding swiping...) is an Activity
whose layout contains a ViewPager
with a PagerTabStrip
, which I styled like this:
// Style the Tab Strip:
Typeface tf = ((MyApplication) getApplication()).getTabStripTypeface(); // Used this to keep a single instance of the typeface (singleton pattern) and avoid mem. leaks
PagerTabStrip strip = (PagerTabStrip) findViewById(R.id.pager_title_strip);
strip.setTabIndicatorColor(getResources().getColor(R.color.myColor));
strip.setDrawFullUnderline(true);
for (int i = 0; i < strip.getChildCount(); ++i) {
View nextChild = strip.getChildAt(i);
if (nextChild instanceof TextView) {
TextView textViewToConvert = (TextView) nextChild;
textViewToConvert.setAllCaps(false);
textViewToConvert.setTypeface(tf);
}
}
不过,这与此问题中提出的问题不同.
This is not the same as the issue presented in this question, though.
我能找到的唯一相关代码是这个,我在其中设置了一个 SpannableString
:
The only related code I can find is this, where I set a SpannableString
:
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
SpannableString s = new SpannableString(mSectionsPagerAdapter.getPageTitle(i));
s.setSpan(new TypefaceSpan(this, "FontName.ttf"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
actionBar.addTab(actionBar.newTab().setText(s).setTabListener(this));
}
...而在我的styles.xml 中,我的Actionbar 选项卡文本的样式如下:
...whereas in my styles.xml, I had the style for the Actionbar's Tab Text like this:
<!-- action bar tabtext style -->
<style name="ActionBarTabText.MyApplication" parent="@android:style/Widget.Holo.ActionBar.TabText">
<item name="android:textAppearance">@android:style/TextAppearance.Holo.Medium</item>
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
<item name="android:textSize">15sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textAllCaps">false</item>
<item name="android:ellipsize">marquee</item>
<item name="android:maxLines">1</item>
</style>
推荐答案
TypefaceSpan
仅适用于三种内置字体.
TypefaceSpan
will only work with the three built-in typefaces.
话虽如此,派生 TypefaceSpan
以使用从本地文件路径加载 Typeface
的地方应该不难.与其将构造函数中的 String
视为面部家族名称,不如将其视为本地文件路径,调整 apply()
以从那里加载它.Typeface
本身不是 Parcelable
,因此您需要使用路径.
That being said, forking TypefaceSpan
to use one where the Typeface
is loaded from a local file path should not be that hard. Rather than treating the String
in the constructor as being a face family name, you would treat it as an local file path, adjusting apply()
to load it from there. Typeface
itself is not Parcelable
, so you would need to work with the path.
从资产中获取 Typeface
的问题是 TypefaceSpan
需要访问 AssetManager
,而且它不容易访问在放入 Parcel
并从其重建后变为一个.
The problem with getting the Typeface
from assets is that the TypefaceSpan
would need access to an AssetManager
, and it would not readily have access to one after being put into and rebuilt from a Parcel
.
我没有使用您的第一种技术,但您遇到问题我并不感到惊讶.
I have not used your first technique, but I am not surprised that you are having problems.
您也可以考虑完全放弃操作栏选项卡并切换到带有选项卡式指示器的 ViewPager
,因为您可以更轻松地进行样式设置,例如 Jake Wharton 的 TabPageIndicator
.
You might also consider dropping action bar tabs entirely and switching to a ViewPager
with a tabbed indicator, as you may have an easier time styling, say, Jake Wharton's TabPageIndicator
.
相关文章