Intereting Posts
Проблема с всплывающим меню в Android ListView Скрыть просмотры точек из MPChart LineChart Слайд-анимация активности с переопределениемPendingTransition имеет странный эффект Android – SwipeRefreshLayout с пустым текстовым просмотром Ошибка контрольной суммы при настройке Android Lollipop Кодирование и декодирование звука для записи звука в формат G711 (PCMU – uLaw) NoClassDefFoundError для приложений, у которых нет новой установки Добавить сенсорные события в класс VrPanoramaView для SDK для Google Картона для Android У вас есть #области в Android / eclipse Как остановить eclipse от автоматического создания фильтров для android logcat? YouTubePlayer не загружает рекламное видео с помощью cueVideo () Как найти абсолютную позицию щелчка при увеличении Помощь при передаче объекта ArrayList объектов в новую активность Изменение цвета / стиля панели инструментов на клике SearchView Как отклонить системный диалог в Android?

Как установить пользовательский шрифт в заголовке ActionBar?

Как (если возможно) установить собственный шрифт в тексте заголовка ActionBar (только – не в тексте вкладки) с шрифтом в моей папке с ресурсами? Я не хочу использовать опцию android: logo.

Solutions Collecting From Web of "Как установить пользовательский шрифт в заголовке ActionBar?"

Я согласен, что это не полностью поддерживается, но вот что я сделал. Вы можете использовать пользовательское представление для панели действий (оно будет отображаться между вашим значком и элементами действия). Я использую настраиваемое представление, и у меня отключен родной заголовок. Все мои действия наследуются от одного действия, которое имеет этот код в 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 выше подход customView потому что он не customView при использовании других элементов Action Bar, таких как расширение представлений действий.

Использование такого класса будет выглядеть примерно так:

 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 вашей деятельности, как показано выше.

 int titleId = getResources().getIdentifier("action_bar_title", "id", "android"); TextView yourTextView = (TextView) findViewById(titleId); yourTextView.setTextColor(getResources().getColor(R.color.black)); yourTextView.setTypeface(face); 

В библиотеке каллиграфии вы можете настроить собственный шрифт через тему приложения, которая также применима к панели действий.

 <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> 

Все, что требуется для активации каллиграфии, привязывает ее к контексту Activity:

 @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(new CalligraphyContextWrapper(newBase)); } 

Пользовательский атрибут по умолчанию – fontPath , но вы можете 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"); } 

Этот код предназначен для устройств post-GINGERBREAD, но это можно легко расширить для работы с панелью действий Sherlock

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); } } 

Используйте новую панель инструментов в библиотеке поддержки, создайте свою панель действий как свою собственную или используйте ниже код

Inflating Textview не является хорошим вариантом, попробуйте Spannable String builder

 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); } } 

Если вы хотите установить шрифт для всех текстовых элементов во всей операции, вы можете использовать что-то вроде этого:

 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); } 

И TypefaceCache:

 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)); } } 

Чтобы добавить к ответу @ 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 FILE: потому что я храню файл в облачном режиме, поэтому у меня есть ссылка на него, чтобы загрузить его.

 /**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; } } } } 

Нам нужно использовать отражения для достижения этого

 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); }