Відповіді:
Я згоден, що це не повністю підтримується, але ось що я зробив. Ви можете використовувати спеціальний перегляд для панелі дій (він відображатиметься між вашою піктограмою та елементами дії). Я використовую нестандартний вигляд, і у мене вимкнена рідна назва Усі мої дії успадковуються від однієї діяльності, яка містить цей код у 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>
Це можна зробити за допомогою спеціального 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
клас передається вашому контексту діяльності та імені шрифту у вашому 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
як показано вище.
textAllCaps
атрибут встановлений на true у нижній частині TextView (наприклад, через тему), то спеціальний шрифт не з’явиться. Це було проблемою для мене, коли я застосував цю техніку до елементів вкладки панелі дій.
assets/fonts/
. Якщо ви просто викинути файли .ttf / .OTF під активи , а не в папці, ви повинні змінити наступний рядок коду відповідно: String.format("fonts/%s", typefaceName)
. Я втратив добрі 10 хвилин, намагаючись зрозуміти це. Якщо ви цього не зробите, ви отримаєтеjava.lang.RuntimeException: Unable to start activity ComponentInfo{com.your.pckage}: java.lang.RuntimeException: native typeface cannot be made
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 v26 + Android Studio 3.0 , цей процес став легким як легкий рух !!
Виконайте наступні дії, щоб змінити шрифт заголовка панелі інструментів:
res > font
згідно шрифтів в XMLУ 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"/>
Насолоджуйтесь стилем шрифту заголовків спеціальної панелі дій !!
Бібліотека каліграфії дозволить вам встановити спеціальний шрифт через тему додатка, який також застосовуватиметься до панелі дій.
<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>
Все, що потрібно для активації каліграфії, - це приєднання її до контексту діяльності:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}
Спеціальний атрибут за замовчуванням є fontPath
, але ви можете надати власний спеціальний атрибут для шляху, ініціалізуючи його у вашому класі Application CalligraphyConfig.Builder
. Вживання препарату android:fontFamily
не рекомендується.
Це некрасивий хак, але ви можете зробити це так (оскільки 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, але його можна легко розширити для роботи з панеллю дій Шерлок
PS На основі коментаря @pjv є кращий спосіб знайти ідентифікатор заголовка рядка дії
final int titleId =
Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
Наступний код буде працювати для всіх версій. Я перевірив це на пристрої з пряниками, а також на пристрої 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 String
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);
}
}
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
щоб не було статичних попереджень для учасників
Якщо ви хочете встановити шрифт для всіх TextViews у всій діяльності, ви можете використовувати щось подібне:
public static void setTypefaceToAll(Activity activity)
{
View view = activity.findViewById(android.R.id.content).getRootView();
setTypefaceToAll(view);
}
public static void setTypefaceToAll(View view)
{
if (view instanceof ViewGroup)
{
ViewGroup g = (ViewGroup) view;
int count = g.getChildCount();
for (int i = 0; i < count; i++)
setTypefaceToAll(g.getChildAt(i));
}
else if (view instanceof TextView)
{
TextView tv = (TextView) view;
setTypeface(tv);
}
}
public static void setTypeface(TextView tv)
{
TypefaceCache.setFont(tv, TypefaceCache.FONT_KOODAK);
}
І Тип кеша:
import java.util.TreeMap;
import android.graphics.Typeface;
import android.widget.TextView;
public class TypefaceCache {
//Font names from asset:
public static final String FONT_ROBOTO_REGULAR = "fonts/Roboto-Regular.ttf";
public static final String FONT_KOODAK = "fonts/Koodak.ttf";
private static TreeMap<String, Typeface> fontCache = new TreeMap<String, Typeface>();
public static Typeface getFont(String fontName) {
Typeface tf = fontCache.get(fontName);
if(tf == null) {
try {
tf = Typeface.createFromAsset(MyApplication.getAppContext().getAssets(), fontName);
}
catch (Exception e) {
return null;
}
fontCache.put(fontName, tf);
}
return tf;
}
public static void setFont(TextView tv, String fontName)
{
tv.setTypeface(getFont(fontName));
}
}
Я просто зробив наступне у функції 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 "
Щоб додати відповідь @ Sam_D, мені довелося це зробити, щоб це працювало:
this.setTitle("my title!");
((TextView)v.findViewById(R.id.title)).setText(this.getTitle());
TextView title = ((TextView)v.findViewById(R.id.title));
title.setEllipsize(TextUtils.TruncateAt.MARQUEE);
title.setMarqueeRepeatLimit(1);
// in order to start strolling, it has to be focusable and focused
title.setFocusable(true);
title.setSingleLine(true);
title.setFocusableInTouchMode(true);
title.requestFocus();
Здається, overkill - посилання на v.findViewById (R.id.title)) двічі - але це єдиний спосіб, який дозволив би мені це зробити.
Щоб оновити правильну відповідь.
по-перше: встановіть заголовок на значення false, оскільки ми використовуємо власні подання
actionBar.setDisplayShowTitleEnabled(false);
по-друге: створити titleview.xml
<?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" >
<TextView
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>
Нарешті:
//font file must be in the phone db so you have to create download file code
//check the code on the bottom part of the download file code.
TypeFace font = Typeface.createFromFile("/storage/emulated/0/Android/data/"
+ BuildConfig.APPLICATION_ID + "/files/" + "font name" + ".ttf");
if(font != null) {
LayoutInflater inflator = LayoutInflater.from(this);
View v = inflator.inflate(R.layout.titleview, null);
TextView titleTv = ((TextView) v.findViewById(R.id.title));
titleTv.setText(title);
titleTv.setTypeface(font);
actionBar.setCustomView(v);
} else {
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(" " + title); // Need to add a title
}
ЗАВАНТАЖИТИ ФАЙЛ FONT: тому що я зберігаю файл у хмарний, тому у мене є посилання на нього, щоб завантажити його.
/**downloadFile*/
public void downloadFile(){
String DownloadUrl = //url here
File file = new File("/storage/emulated/0/Android/data/" + BuildConfig.APPLICATION_ID + "/files/");
File[] list = file.listFiles();
if(list == null || list.length <= 0) {
BroadcastReceiver onComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try{
showContentFragment(false);
} catch (Exception e){
}
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadUrl));
request.setVisibleInDownloadsUi(false);
request.setDestinationInExternalFilesDir(this, null, ModelManager.getInstance().getCurrentApp().getRegular_font_name() + ".ttf");
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} else {
for (File files : list) {
if (!files.getName().equals("font_name" + ".ttf")) {
BroadcastReceiver onComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try{
showContentFragment(false);
} catch (Exception e){
}
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadUrl));
request.setVisibleInDownloadsUi(false);
request.setDestinationInExternalFilesDir(this, null, "font_name" + ".ttf");
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} else {
showContentFragment(false);
break;
}
}
}
}
Не потрібно спеціального перегляду тексту!
По-перше, вимкніть заголовок у тообарі у вашому коді Java: getSupportActionBar (). SetDisplayShowTitleEnabled (false);
Потім просто додайте TextView на панель інструментів:
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="18sp"
android:fontFamily="@font/roboto" />
</android.support.v7.widget.Toolbar>
Спробуйте скористатися цим
TextView headerText= new TextView(getApplicationContext());
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT);
headerText.setLayoutParams(lp);
headerText.setText("Welcome!");
headerText.setTextSize(20);
headerText.setTextColor(Color.parseColor("#FFFFFF"));
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/wesfy_regular.ttf");
headerText.setTypeface(tf);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(headerText);
Для цього нам потрібно використовувати роздуми
final int titleId = activity.getResources().getIdentifier("action_bar_title", "id", "android");
final TextView title;
if (activity.findViewById(titleId) != null) {
title = (TextView) activity.findViewById(titleId);
title.setTextColor(Color.BLACK);
title.setTextColor(configs().getColor(ColorKey.GENERAL_TEXT));
title.setTypeface(configs().getTypeface());
} else {
try {
Field f = bar.getClass().getDeclaredField("mTitleTextView");
f.setAccessible(true);
title = (TextView) f.get(bar);
title.setTextColor(Color.BLACK);
title.setTypeface(configs().getTypeface());
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
}
}
СПРОБУЙТЕ ЦЕ
public void findAndSetFont(){
getActionBar().setTitle("SOME TEST TEXT");
scanForTextViewWithText(this,"SOME TEST TEXT",new SearchTextViewInterface(){
@Override
public void found(TextView title) {
}
});
}
public static void scanForTextViewWithText(Activity activity,String searchText, SearchTextViewInterface searchTextViewInterface){
if(activity == null|| searchText == null || searchTextViewInterface == null)
return;
View view = activity.findViewById(android.R.id.content).getRootView();
searchForTextViewWithTitle(view, searchText, searchTextViewInterface);
}
private static void searchForTextViewWithTitle(View view, String searchText, SearchTextViewInterface searchTextViewInterface)
{
if (view instanceof ViewGroup)
{
ViewGroup g = (ViewGroup) view;
int count = g.getChildCount();
for (int i = 0; i < count; i++)
searchForTextViewWithTitle(g.getChildAt(i), searchText, searchTextViewInterface);
}
else if (view instanceof TextView)
{
TextView textView = (TextView) view;
if(textView.getText().toString().equals(searchText))
if(searchTextViewInterface!=null)
searchTextViewInterface.found(textView);
}
}
public interface SearchTextViewInterface {
void found(TextView title);
}