How to Set a Custom Font in the ActionBar Title?

后端 未结 17 1519
面向向阳花
面向向阳花 2020-11-22 09:46

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.

相关标签:
17条回答
  • 2020-11-22 10:18

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

    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:

    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));
        }
    }
    
    0 讨论(0)
  • 2020-11-22 10:18

    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) {
            }
        }
    
    0 讨论(0)
  • 2020-11-22 10:19

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

    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.

    0 讨论(0)
  • 2020-11-22 10:22

    To update the correct answer.

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

        actionBar.setDisplayShowTitleEnabled(false);
    

    secondly : create 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.

    /**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;
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 10:23

    No custom textview is required!

    First, disable the title in the toobar in your java code : getSupportActionBar().setDisplayShowTitleEnabled(false);

    Then, simply add a TextView inside the toolbar :

    <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>
    
    0 讨论(0)
提交回复
热议问题