如何在ActionBar标题中设置自定义字体?

时间:2022-12-05 07:26:22

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.

我如何(如果可能的话)在ActionBar标题文本(只有-不是选项卡文本)中设置自定义字体,在我的assets文件夹中设置字体?我不想使用android:logo选项。

14 个解决方案

#1


200  

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:

我同意这不是完全支持的,但我是这么做的。您可以为操作栏使用自定义视图(它将显示在图标和操作项之间)。我正在使用一个自定义视图,并且禁用了本机标题。我的所有活动都继承了一个活动,它在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 (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>

#2


407  

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.

您可以使用自定义TypefaceSpan类来实现这一点。它优于上面提到的customView方法,因为它在使用其他动作栏元素(如扩展动作视图)时不会中断。

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:

自定义TypefaceSpan类将传递您的活动上下文和资产/字体目录中的字体名称。它加载文件并在内存中缓存一个新的字体实例。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);
    }
}

Simply copy the above class into your project and implement it in your activity's onCreate method as shown above.

只需将上面的类复制到项目中,并在活动的onCreate方法中实现它,如上所示。

#3


147  

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

#4


13  

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.

默认的自定义属性是fontPath,但是您可以通过在应用程序类中用CalligraphyConfig.Builder初始化路径来为路径提供您自己的自定义属性。android:fontFamily被禁止使用。

#5


11  

It's an ugly hack but you can do it like this (since action_bar_title is hidden) :

这是一个很丑的技巧,但是你可以这样做(因为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");
    }

This code is for post-GINGERBREAD devices but this can be easily extended to work with actionbar Sherlock as well

这段代码是针对后姜饼设备的,但是也可以很容易地扩展到actionbar Sherlock中

P.S. Based on @pjv comment there's a better way to find action bar title id

基于@pjv的评论,有一种更好的方法找到动作条标题id

final int titleId = 
    Resources.getSystem().getIdentifier("action_bar_title", "id", "android");

#6


8  

Following code will work for all the versions. I did checked this in a device with gingerbread as well as on JellyBean device

以下代码适用于所有版本。我在姜饼设备和豆粒软糖设备上都做过检查

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

#7


8  

use new toolbar in support library design your actionbar as your own or use below code

在支持库中使用新的工具栏,将actionbar设计成您自己的或者使用下面的代码

Inflating Textview is not an good option try Spannable String builder

放大Textview不是一个好的选择,可以尝试使用可扩展的字符串构建器。

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

copy below class

复制下面的类

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

}

#8


7  

From Android Support Library v26 + Android Studio 3.0 onwards, this process has become easy as a flick!!

从Android支持库v26 + Android Studio 3.0开始,这个过程变得像电影一样简单!

Follow these steps to change the font of Toolbar Title:

按照以下步骤更改工具栏标题字体:

  1. Read Downloadable Fonts & select any font from the list (my recommendation) or load a custom font to res > font as per Fonts in XML
  2. 阅读可下载的字体并从列表中选择任何字体(我的建议),或者按照XML中的字体将自定义字体加载到res >字体
  3. In res > values > styles, paste the following (use your imagination here!)

    在res >值>样式中,粘贴以下内容(请在这里使用您的想象力!)

    <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>
    
  4. Insert a new line in your Toolbar properties app:titleTextAppearance="@style/TextAppearance.TabsFont" as shown below

    在工具栏属性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"/>
    
  5. Enjoy Custom Actionbar Title font styling!!

    享受自定义Actionbar标题字体样式!

#9


3  

I just did the following inside the onCreate() function:

我在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);

I am using the Support Libraries, if you are not using them I guess you should switch to getActionBar() instead of getSupportActionBar().

我正在使用支持库,如果您不使用它们,我想您应该切换到getActionBar()而不是getSupportActionBar()。

In Android Studio 3 you can add custom fonts following this instructions https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html and then use your newly added font in "font_to_be_used"

在Android Studio 3中,您可以根据以下说明添加自定义字体:https://developer.android.com/guide/topics/uis/look -feel/fonts- In -xml.html,然后在“font_to_be_used”中使用新添加的字体

#10


2  

If you want to set typeface to all the TextViews in the entire Activity you can use something like this:

如果你想为整个活动中的所有textview设置字体,你可以这样使用:

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

And the TypefaceCache:

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

#11


1  

To add to @Sam_D's answer, I had to do this to make it work:

为了增加@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();

It seems like overkill - referencing v.findViewById(R.id.title)) twice - but that's the only way it would let me do it.

这看起来有点过头了——引用了vfindviewbyid (R.id.title)两次——但这是它允许我这么做的唯一方式。

#12


1  

To update the correct answer.

更新正确答案。

firstly : set the title to false, because we are using custom view

首先:将标题设为false,因为我们使用的是自定义视图

    actionBar.setDisplayShowTitleEnabled(false);

secondly : create titleview.xml

其次:创建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>

Lastly :

最后:

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

DOWNLOAD FONT FILE : because i am storing the file into cloudinary so I have link on it to download it.

下载字体文件:因为我把文件存储在cloudinary,所以我有链接下载它。

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

#13


0  

We need to use reflections for achieving this

我们需要利用反射来实现这一点

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

#14


-1  

TRY THIS

试试这个

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

#1


200  

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:

我同意这不是完全支持的,但我是这么做的。您可以为操作栏使用自定义视图(它将显示在图标和操作项之间)。我正在使用一个自定义视图,并且禁用了本机标题。我的所有活动都继承了一个活动,它在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 (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>

#2


407  

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.

您可以使用自定义TypefaceSpan类来实现这一点。它优于上面提到的customView方法,因为它在使用其他动作栏元素(如扩展动作视图)时不会中断。

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:

自定义TypefaceSpan类将传递您的活动上下文和资产/字体目录中的字体名称。它加载文件并在内存中缓存一个新的字体实例。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);
    }
}

Simply copy the above class into your project and implement it in your activity's onCreate method as shown above.

只需将上面的类复制到项目中,并在活动的onCreate方法中实现它,如上所示。

#3


147  

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

#4


13  

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.

默认的自定义属性是fontPath,但是您可以通过在应用程序类中用CalligraphyConfig.Builder初始化路径来为路径提供您自己的自定义属性。android:fontFamily被禁止使用。

#5


11  

It's an ugly hack but you can do it like this (since action_bar_title is hidden) :

这是一个很丑的技巧,但是你可以这样做(因为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");
    }

This code is for post-GINGERBREAD devices but this can be easily extended to work with actionbar Sherlock as well

这段代码是针对后姜饼设备的,但是也可以很容易地扩展到actionbar Sherlock中

P.S. Based on @pjv comment there's a better way to find action bar title id

基于@pjv的评论,有一种更好的方法找到动作条标题id

final int titleId = 
    Resources.getSystem().getIdentifier("action_bar_title", "id", "android");

#6


8  

Following code will work for all the versions. I did checked this in a device with gingerbread as well as on JellyBean device

以下代码适用于所有版本。我在姜饼设备和豆粒软糖设备上都做过检查

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

#7


8  

use new toolbar in support library design your actionbar as your own or use below code

在支持库中使用新的工具栏,将actionbar设计成您自己的或者使用下面的代码

Inflating Textview is not an good option try Spannable String builder

放大Textview不是一个好的选择,可以尝试使用可扩展的字符串构建器。

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

copy below class

复制下面的类

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

}

#8


7  

From Android Support Library v26 + Android Studio 3.0 onwards, this process has become easy as a flick!!

从Android支持库v26 + Android Studio 3.0开始,这个过程变得像电影一样简单!

Follow these steps to change the font of Toolbar Title:

按照以下步骤更改工具栏标题字体:

  1. Read Downloadable Fonts & select any font from the list (my recommendation) or load a custom font to res > font as per Fonts in XML
  2. 阅读可下载的字体并从列表中选择任何字体(我的建议),或者按照XML中的字体将自定义字体加载到res >字体
  3. In res > values > styles, paste the following (use your imagination here!)

    在res >值>样式中,粘贴以下内容(请在这里使用您的想象力!)

    <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>
    
  4. Insert a new line in your Toolbar properties app:titleTextAppearance="@style/TextAppearance.TabsFont" as shown below

    在工具栏属性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"/>
    
  5. Enjoy Custom Actionbar Title font styling!!

    享受自定义Actionbar标题字体样式!

#9


3  

I just did the following inside the onCreate() function:

我在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);

I am using the Support Libraries, if you are not using them I guess you should switch to getActionBar() instead of getSupportActionBar().

我正在使用支持库,如果您不使用它们,我想您应该切换到getActionBar()而不是getSupportActionBar()。

In Android Studio 3 you can add custom fonts following this instructions https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html and then use your newly added font in "font_to_be_used"

在Android Studio 3中,您可以根据以下说明添加自定义字体:https://developer.android.com/guide/topics/uis/look -feel/fonts- In -xml.html,然后在“font_to_be_used”中使用新添加的字体

#10


2  

If you want to set typeface to all the TextViews in the entire Activity you can use something like this:

如果你想为整个活动中的所有textview设置字体,你可以这样使用:

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

And the TypefaceCache:

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

#11


1  

To add to @Sam_D's answer, I had to do this to make it work:

为了增加@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();

It seems like overkill - referencing v.findViewById(R.id.title)) twice - but that's the only way it would let me do it.

这看起来有点过头了——引用了vfindviewbyid (R.id.title)两次——但这是它允许我这么做的唯一方式。

#12


1  

To update the correct answer.

更新正确答案。

firstly : set the title to false, because we are using custom view

首先:将标题设为false,因为我们使用的是自定义视图

    actionBar.setDisplayShowTitleEnabled(false);

secondly : create titleview.xml

其次:创建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>

Lastly :

最后:

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

DOWNLOAD FONT FILE : because i am storing the file into cloudinary so I have link on it to download it.

下载字体文件:因为我把文件存储在cloudinary,所以我有链接下载它。

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

#13


0  

We need to use reflections for achieving this

我们需要利用反射来实现这一点

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

#14


-1  

TRY THIS

试试这个

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