web-dev-qa-db-fra.com

Comment changer la police personnalisée de l'élément de menu Android?

J'ai le code Android Java et XML suivant. Je souhaite modifier la police des éléments de menu de mon application. Je sais seulement que nous pouvons changer la police de TextView en utilisant setTypeface mais ne pouvant pas trouver quand même pour Menu Item.

Java Code-:

@Override
public boolean onCreateOptionsMenu(Menu menu) {    
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override    
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {     
        case R.id.action_refresh1:                                          
            Toast.makeText(this, "Item1 Selected", Toast.LENGTH_SHORT)
            .show();      
        break;

        case R.id.action_refresh2:                                          
            Toast.makeText(this, "Item2 Selected", Toast.LENGTH_SHORT)
            .show();      
            break;

        default:      
            break;
   }
}

Code XML-:  

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item
    Android:id="@+id/action_refresh1"
    Android:orderInCategory="100"
    Android:showAsAction="always"
    Android:title="Item1"/>

<item
    Android:id="@+id/action_refresh2"
    Android:orderInCategory="100"
    Android:showAsAction="always"
    Android:title="Item2"/>
</menu>

Je veux changer la police de deux éléments de menu, mais je ne sais pas comment intégrer la règle de configuration pour l'élément de menu.

17
animation123

vous devez fournir une disposition personnalisée pour l'élément de menu.

Tout d’abord, dans votre menu XML, définissez l’un des éléments suivants:

CASE 1 si vous utilisez la bibliothèque de support:

<menu
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">
    <item
        Android:id="@+id/action_save"
        Android:title="@string/action_save"
        Android:icon="@drawable/ic_action_save"
        Android:orderInCategory="100"
        app:showAsAction="always"
        app:actionLayout="@layout/layout_menu_save"/>
</menu>

CASE 2 si vous utilisez pas en utilisant la bibliothèque de support:

<menu
    xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:id="@+id/action_save"
        Android:title="@string/action_save"
        Android:icon="@drawable/ic_action_save"
        Android:orderInCategory="100"
        Android:showAsAction="always"
        Android:actionLayout="@layout/layout_menu_save"/>
</menu>

Ensuite, dans l'actionLayout (layout_menu_save.xml dans mon exemple), écrivez ce qui suit:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"

    Android:orientation="horizontal"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:background="@drawable/background_transparent_stateful">

    <com.example.YourCustomTypefaceTextView
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_marginStart="8dp"
        Android:layout_marginLeft="8dp"
        Android:layout_marginEnd="8dp"
        Android:layout_marginRight="8dp"
        Android:gravity="center_vertical"
        Android:text="@string/action_save"/>

    <ImageView
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_marginEnd="8dp"
        Android:layout_marginRight="8dp"
        Android:gravity="center_vertical"
        Android:src="@drawable/ic_action_save"
        Android:contentDescription="@string/action_save"/>

</LinearLayout>

L'arrière-plan dessinable (background_transparent_stateful) est utile pour avoir un retour tactile sur votre mise en page personnalisée:

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <item Android:state_pressed="true"
        Android:drawable="#20FFFFFF">
    </item>
    <item
        Android:drawable="@Android:color/transparent">
    </item>
</selector>

De cette façon, vous aurez un texte avec une police personnalisée à gauche sous la forme d’une étiquette avec une icône à droite.

Évidemment, vous pouvez personnaliser la mise en page comme vous préférez!


MODIFIER:
Si vous utilisez la bibliothèque de support et que votre thème d'activité étend l'AppCompatTheme, vous pouvez obtenir le résultat typique "effet d'ondulation" de Lollipop pour un meilleur retour tactile . Remplacez simplement l'arrière-plan personnalisé par:

<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"

    Android:orientation="horizontal"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:background="?attr/selectableItemBackgroundBorderless">
    ...
</LinearLayout>
18
araks

XML

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:app="http://schemas.Android.com/apk/res-auto">

        <item
            Android:id="@+id/action_edit"
            Android:title="@string/edit"
            Android:visible="true"
            app:showAsAction="always" />
    </menu>

EN ACTIVITÉ OR EN FRAGMENT 

@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

            Typeface face = Typeface.createFromAsset(getActivity().getAssets(),"fonts/OpenSans-Regular.ttf");    //  THIS
            TypefaceSpan face = new TypefaceSpan("<REPLACE_WITH_FONT_NAME>"); // OR  THIS 
            SpannableStringBuilder title = new SpannableStringBuilder(getContext().getString(R.string.edit));
            title.setSpan(face, 0, title.length(), 0);
            menu.add(Menu.NONE, R.id.action_edit, 0, title); // THIS 
            MenuItem menuItem = menu.findItem(R.id.action_edit); // OR THIS 
            menuItem.setTitle(title);
        super.onCreateOptionsMenu(menu, inflater);
    }
8
NickUnuchek

Vous pouvez également utiliser un SpannableStringBuilder lorsque vous ajoutez un élément de menu avec un TypefaceSpan. Pour chaque élément de menu, faites quelque chose comme

TypefaceSpan span = new TypefaceSpan("<REPLACE_WITH_FONT_NAME>");
SpannableStringBuilder title = new SpannableStringBuilder("My Menu Item Title");
title.setSpan(span, 0, title.length(), 0);
menu.add(Menu.NONE, id, index, title);
3
Stephen Johnson

Créer un style dans styles.xml

 <style name="Style_TextView">
            <item name="fontFamily">@font/myriadproregular</item>
 </style>

Ajoutez le code ci-dessous dans Android.support.design.widget.NavigationView 

 app:itemTextAppearance="@style/Style_TextView"

Remarque: cela fonctionne pour Android.support.design.widget.NavigationView

2
Suman

J'ai trouvé cette solution utile pour moi. J'espère que cela aidera de nouveaux surfeurs.

votre menu main.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
>
  <item Android:id="@+id/item1"
  Android:title="User"
  Android:orderInCategory="100"
  Android:visible="true"
  app:showAsAction="always"
  app:actionViewClass="Android.widget.Button"
/>
</menu>

Après avoir gonflé le menu personnalisé, vous pouvez faire référence à l’élément du menu. Lorsque vous obtenez la référence à l'élément de menu, vous pourrez personnaliser l'élément pour afficher l'icône et le texte Unicode. Votre fichier image d'icône doit être stocké dans le 

dossier res/drawable.

@Override
   public boolean onCreateOptionsMenu(Menu menu) {
     // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);

   //reference to the item of the menu
   MenuItem i=menu.findItem(R.id.item1);
   Button button_menu =(Button) i.getActionView();

   if(itemuser!=null){
   // Create Typeface object to use unicode font in assets folder
   Typeface font= Typeface.createFromAsset(getApplicationContext().getAssets(),"fonts/arial.ttf");
   // Set unicode font to menu item
   button_menu .setTypeface(font);  
   // Set item text and color
   button_menu .setText(getResources().getString(R.string._text));
   button_menu .setTextColor(Color.WHITE);
   // Make item background transparent
   button_menu .setBackgroundColor(Color.TRANSPARENT);
   // Show icon next to the text
   Drawable icon=getApplicationContext().getResources().getDrawable( R.drawable.user);
   button_menu .setCompoundDrawablesWithIntrinsicBounds( icon, null, null, null );
}

return true;

   }
1
brahmy adigopula

La réponse de @brahmyadigopula fonctionne bien.

Voici une version plus complète par souci de simplification:

Le menu

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools">
    <item
        Android:id="@+id/update"
        Android:showAsAction="always"
        Android:title="@string/menu_update"
        tools:ignore="UnusedAttribute"
        Android:actionViewClass="Android.widget.Button"/>
</menu>

Dans votre activité ou fragment:

        // Inflater the menu based on the layout above
        inflater.inflate(menuRes, menu);


        // Set font type face
        if (setCustomFontType){
            final MenuItem menuItem = menu.findItem(R.id.update);
            String title = menuItem.getTitle().toString();

            Button button_menu = (Button) menuItem.getActionView();
            button_menu.setTypeface("<REPLACE_WITH_FONT_NAME>");
            button_menu.setText(title);
            button_menu.setTextColor(Color.WHITE);
            button_menu.setBackgroundColor(_getResources().getColor(R.color.transparent_color));
            button_menu.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onOptionsItemSelected(menuItem);
                }
            });
        }

        super.onCreateOptionsMenu(menu, inflater);
0
Joolah

Si votre application ne doit fonctionner que sous Android P ie (API de niveau 28) et supérieur, vous pouvez construire un TypefaceSpan à partir d'un Typeface dans onPrepareOptionsMenu. Sinon, vous pouvez utiliser une classe CustomTypefaceSpan comme ceci answer suggère:

public boolean onPrepareOptionsMenu(Menu menu) {
    int customFontId = R.font.metropolis_medium;
    for (int i = 0; i < menu.size(); i++) {
        MenuItem menuItem = menu.getItem(i);
        String menuTitle = menuItem.getTitle().toString();
        Typeface typeface = ResourcesCompat.getFont(this, customFontId);
        SpannableString spannableString = new SpannableString(menuTitle);
        // For demonstration purposes only, if you need to support < API 28 just use the CustomTypefaceSpan class only.
        if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.P) {
            TypefaceSpan typefaceSpan = typeface != null ?
                    new TypefaceSpan(typeface) :
                    new TypefaceSpan("sans-serif");
            spannableString.setSpan(typefaceSpan, 0, menuTitle.length(), 
                    Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        } else {
            CustomTypefaceSpan customTypefaceSpan = typeface != null ?
                    new CustomTypefaceSpan(typeface) :
                    new CustomTypefaceSpan(Typeface.defaultFromStyle(Typeface.NORMAL));
            spannableString.setSpan(customTypefaceSpan, 0, menuTitle.length(),
                    Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        }
        menuItem.setTitle(spannableString);
    }
    return true;
}

main.menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">
    <item
        Android:id="@+id/settings"
        Android:onClick="openSettings"
        Android:title="@string/settings"
        app:showAsAction="never" />
    <item
        Android:id="@+id/about"
        Android:onClick="openAbout"
        Android:title="@string/about"
        app:showAsAction="never" />
</menu>

Avant après:

Before & After

0
shash678