web-dev-qa-db-fra.com

Comment définir une police personnalisée dans le titre ActionBar?

Comment (si possible) pourrais-je définir une police personnalisée dans un texte de titre ActionBar (uniquement - pas le texte de l'onglet) avec une police dans mon dossier d'éléments? Je ne souhaite pas utiliser l'option Android: logo. 

244
user742030

Je conviens que ce n'est pas complètement pris en charge, mais voici ce que j'ai fait. Vous pouvez utiliser une vue personnalisée pour votre barre d’actions (elle s’affichera entre votre icône et vos actions). J'utilise une vue personnalisée et le titre natif est désactivé. Toutes mes activités héritent d'une seule activité, qui a ce code dans 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);

Et ma mise en page xml (R.layout.titleview dans le code ci-dessus) ressemble à ceci:

<?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>
206
Sam Dozor

Vous pouvez le faire en utilisant une classe TypefaceSpan personnalisée. Elle est supérieure à l'approche customView indiquée ci-dessus, car elle ne casse pas lors de l'utilisation d'autres éléments de la barre d'action, tels que le développement des vues d'action.

L'utilisation d'une telle classe ressemblerait à ceci:

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

La classe TypefaceSpan personnalisée reçoit le contexte de votre activité et le nom d'une police de caractères de votre répertoire assets/fonts. Il charge le fichier et met en cache une nouvelle instance Typeface en mémoire. L'implémentation complète de TypefaceSpan est étonnamment simple:

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

Copiez simplement la classe ci-dessus dans votre projet et implémentez-la dans la méthode onCreate de votre activité, comme indiqué ci-dessus.

417
twaddington
int titleId = getResources().getIdentifier("action_bar_title", "id",
            "Android");
    TextView yourTextView = (TextView) findViewById(titleId);
    yourTextView.setTextColor(getResources().getColor(R.color.black));
    yourTextView.setTypeface(face);
149
Digit

À partir de Android Support Library v26 + Android Studio 3.0, ce processus est devenu très simple !!

Suivez ces étapes pour changer la police du titre de la barre d’outils:

  1. Lire Polices téléchargeables & sélectionnez une police dans la liste (ma recommandation) ou chargez une police personnalisée dans res > font selon Polices in XML
  2. Dans res > values > styles, collez le texte suivant (utilisez votre imagination ici! _)

    <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>
    
  3. Insérez une nouvelle ligne dans les propriétés de votre barre d'outils app:titleTextAppearance="@style/TextAppearance.TabsFont" comme indiqué ci-dessous

    <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"/>
    
  4. Profitez du style de police Titre Actionbar personnalisé!

18
Mohammed Mukhtar

La bibliothèque Calligraphy vous permet de définir une police personnalisée dans le thème de l'application, qui s'appliquerait également à la barre d'action.

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

Pour activer la calligraphie, il suffit de l'attacher à votre contexte d'activité:

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

L'attribut personnalisé par défaut est fontPath, mais vous pouvez fournir votre propre attribut personnalisé pour le chemin en l'initialisant dans votre classe Application avec CalligraphyConfig.Builder. L'utilisation de Android:fontFamily a été découragée.

13
thoutbeckers

C'est un bidouillage moche mais vous pouvez le faire comme ça (puisque action_bar_title est caché):

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

Ce code est destiné aux appareils post-pain d'épice, mais cela peut être facilement étendu pour fonctionner également avec la barre d'actions Sherlock

P.S. Sur la base du commentaire @pjv, il existe un meilleur moyen de trouver l'identifiant du titre de la barre d'action.

final int titleId = 
    Resources.getSystem().getIdentifier("action_bar_title", "id", "Android");
11
Bostone

utiliser une nouvelle barre d'outils dans la bibliothèque de support, concevez votre barre d'actions comme étant la vôtre ou utilisez le code ci-dessous

Gonfler Textview n'est pas une bonne option, essayez 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);

copie ci-dessous classe

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
Jinu

Le code suivant fonctionnera pour toutes les versions. J'ai vérifié cela dans un appareil avec Gingerbread ainsi que sur 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);
        }
    }
8
Napolean
    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);
4
kapsid

Je viens de faire ce qui suit dans la fonction 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);

J'utilise les bibliothèques de support. Si vous ne les utilisez pas, vous devriez passer à getActionBar () au lieu de getSupportActionBar ().

Dans Android Studio 3, vous pouvez ajouter des polices personnalisées en suivant ces instructions https://developer.Android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html , puis utilisez votre nouveau Ajout de la police dans "font_to_be_used"

3
Seven

Si vous souhaitez définir une police de caractères pour toutes les TextViews de toute l'activité, vous pouvez utiliser quelque chose comme ceci:

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

Et le 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));
    }
}
2
user2136334

Aucune visualisation de texte personnalisée n'est requise!

Commencez par désactiver le titre dans la barre d'outils de votre code Java: getSupportActionBar (). setDisplayShowTitleEnabled (false);

Ensuite, ajoutez simplement un TextView dans la barre d’outils:

<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>
1
Apurva Thorat

Pour ajouter à la réponse de @ Sam_D, je devais le faire pour que cela fonctionne:

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

Cela ressemble à de l'overkill - référencement v.findViewById (R.id.title)) deux fois - mais c'est la seule façon pour moi de le faire.

1
IgorGanapolsky

Pour mettre à jour la réponse correcte.

firstly: définissez le titre sur false, car nous utilisons l'affichage personnalisé

    actionBar.setDisplayShowTitleEnabled(false);

deuxièmement: créer 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>

Enfin : 

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

TELECHARGER LE FICHIER DE POLICE: parce que je stocke le fichier dans cloudinary, j'ai donc un lien pour le télécharger.

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

Nous devons utiliser des réflexions pour y parvenir.

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

Il suffit de copier et coller une police de style à partir d'un site Web du type https://igfonts.io/

Ensuite, dans strings.xml, il vous suffit de changer le nom du titre.

<resources>
  <string name="app_name">???????????????? ???????? ????????????????????</string> // Title name
  <string name="action_settings">Settings</string>
  <string name="title_activity_item_info">ItemInfo</string>
</resources>
0
Samaritan

Essayez d'utiliser ceci

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