2014-02-21 3 views
12

У меня есть следующий код Java и XML для Android. Я хочу изменить шрифт пунктов меню моего приложения. Я знаю только, что мы можем изменить шрифт TextView с помощью setTypeface, но так и не смогли найти элемент меню.Как изменить пользовательский шрифт элемента меню Android?

JAVA код-:

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


    } 



} 

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> 

Я хочу, чтобы изменить шрифт два пункта меню, но не знаю, как интегрировать settypface для пункта меню.

+1

может быть, это даст вы подсказку :) см. ответ ниже :) http://stackoverflow.com/questions/4135 699/как-установить-шрифт для опций-меню – superJen

ответ

14

Вы должны предоставить пользовательский макет для пункта меню.

Во-первых, в меню XML установить одно из следующих действий

СЛУЧАЙ 1 если вы используете библиотеку поддержки:

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

СЛУЧАЙ 2 если вы не с помощью поддержка библиотеки:

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

в actionLayout (layout_menu_save.xml в моем примере) написать следующее:

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

Фоновый Drawable (background_transparent_stateful) полезно иметь сенсорную обратную связь на пользовательском макете:

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

Таким образом, вы с текстом с пользовательским шрифтом слева в виде метки с иконкой справа.

Очевидно, что вы можете настроить макет по своему усмотрению!


EDIT:
Если вы используете библиотеку поддержки и ваша деятельность Тема расширяет AppCompatTheme вы можете получить типичную Lollipop «мультипликационный эффект» для более перспективных сенсорной обратной связи. Просто замените собственный фон с:

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

Hm. Такие работы, но не совсем (по крайней мере, на L). Вам нужно изменить свой item.setOnMenuItemClickListener() на item.getActionView(). SetOnClickListener() и сделать ваш LinearLayout доступным и настраиваемым для регистрации кликов. Кроме того, эффект волнения застревает после анимации. – Eduard

+0

Hi @EduardK. Спасибо за ответ! Это может быть ошибка, я столкнулся с аналогичным поведением в некоторых конкретных конфигурациях Activity. Вы используете библиотеку поддержки Android? – araks

+4

Да, используя библиотеку поддержки. Похоже, я только что исправил это. Необходимо только добавить clickable = "true" и focusable = "true" к LinearLayout. Тогда и то и другое, эффект пульсации и щелчки работают правильно. (не добавляйте focusableInTouchMode) – Eduard

2

Вы также можете использовать SpannableStringBuilder при добавлении пункта меню с TypefaceSpan. Для каждого пункта меню сделать что-то вроде

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

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> 

В ДЕЯТЕЛЬНОСТИ ИЛИ В фрагментировать

@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); 
    } 
+0

Imho - лучший способ установить пользовательский шрифт для пунктов меню. – Elisa

0

я нашел это решение является полезным для меня .hope это поможет полностью новые серферов ,

ваше меню 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> 

После того, как вы раздули пользовательское меню, вы можете сделать ссылку на пункт меню. Когда вы получите ссылку на пункт меню, вы сможете настроить элемент для отображения значка и текста Юникода. Файл изображения значков должен храниться в

res/drawable folder.

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

    } 
0

Ответ на @brahmyadigopula работает хорошо.

Вот только более полная версия для упрощения:

Меню

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

В вашей деятельности или фрагмента:

 // 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); 
Смежные вопросы