如何为"选项"菜单设置字体?

Pet*_*son 34 android

当我创建一个选项菜单时,项目似乎默认为本机"sans"字体.当我看商业应用程序时,他们似乎大多数都做同样的事情.是否可以为选项菜单项设置字体大小,颜色重量或字体?

提前致谢.

And*_*ack 64

您可以自定义选项菜单,包括:

  1. 添加自定义字体

  2. 更改字体大小

  3. 更改字体颜色

  4. 将背景设置为Drawable资源(例如图像,边框,渐变)

要将背景更改为边框或渐变,您必须在res被调用中创建资源文件夹,drawable并在其中创建边框XML或渐变XML.

这可以以编程方式完成,如下所示:

public class CustomMenu extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public boolean onCreateOptionsMenu(android.view.Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.cool_menu, menu);
        getLayoutInflater().setFactory(new Factory() {
            public View onCreateView(String name, Context context,
                    AttributeSet attrs) {

                if (name.equalsIgnoreCase(
                        "com.android.internal.view.menu.IconMenuItemView")) {
                    try {
                        LayoutInflater li = LayoutInflater.from(context);
                        final View view = li.createView(name, null, attrs);
                        new Handler().post(new Runnable() {
                            public void run() {
                                // set the background drawable if you want that
                                //or keep it default -- either an image, border
                                //gradient, drawable, etc.
                                view.setBackgroundResource(R.drawable.myimage);
                                ((TextView) view).setTextSize(20); 

                                // set the text color
                                Typeface face = Typeface.createFromAsset(
                                        getAssets(),"OldeEnglish.ttf");     
                                ((TextView) view).setTypeface(face);
                                ((TextView) view).setTextColor(Color.RED);
                            }
                        });
                        return view;
                    } catch (InflateException e) {
                        //Handle any inflation exception here
                    } catch (ClassNotFoundException e) {
                        //Handle any ClassNotFoundException here
                    }
                }
                return null;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.AboutUs:
            Intent i = new Intent("com.test.demo.ABOUT");
            startActivity(i);
            break;
        case R.id.preferences:
            Intent p = new Intent("com.test.demo.PREFS");
            startActivity(p);
            break;
        case R.id.exit:
            finish();
            break;
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

别忘了创建menures文件夹中调用的文件夹,并在文件夹内menu为您的菜单创建一个XML(例如cool_menu.xml),例如:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item  android:title="about"android:id="@+id/AboutUs" /> 
    <item android:title="Prefs" android:id="@+id/preferences" /> 
    <item android:title="Exit" android:id="@+id/exit" /> 
</menu>
Run Code Online (Sandbox Code Playgroud)

然后输出将是这样的:

在此输入图像描述

  • 它对我不起作用,我得到了下一个例外:已经在这个LayoutInflater上设置了一个工厂 (24认同)
  • 同样对我来说 - "这个LayoutInflater上已经设置了一个工厂" (3认同)
  • 嗨,当我运行上面的代码(略微修改,请参阅以下注释)时,菜单项的外观仅在我第一次打开选项菜单时更改.如果我退出选项菜单(通过选择一个选项,按后退按钮或按菜单按钮)然后再次打开它,它的外观将恢复为默认外观.如何使修改持久化?我正在开发API级别8. (2认同)
  • @AndroidStack 抱歉回复晚了。我更改了文本大小和文本颜色,从而产生了一个选项菜单,其中选项中的文本是红色的并且比平常大。我第二次调用选项菜单时,文本再次变为白色并且具有默认大小(不知道确切的大小,但严格小于 20)。 (2认同)

dsg*_*dsg 10

@Android Stack,当我读到你的回答时,我开始恐慌地认为我必须使用"工厂".

我搜索了一下,我了解到你可以使用菜单项的自定义视图.只需在菜单项上调用setActionView即可.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Inflate the menu items for use in the action bar
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu, menu);

    // Get the root inflator. 
    LayoutInflater baseInflater = (LayoutInflater)getBaseContext()
           .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // Inflate your custom view.
    View myCustomView = baseInflater.inflate(R.layout.my_custom_view, null);
    menu.findItem(R.id.my_custom_menu_icon).setActionView(myCustomView);


    // If myCustomView has additional children, you might have to inflate them separately here.
    // In my case, I used buttons in my custom view, and registered onClick listeners at this point.

 }
Run Code Online (Sandbox Code Playgroud)

您的实现my_custom_view可以是您想要的任何视图(尽管它可能必须有一个LinearLayout作为根元素).例如,您可以使用@ R4j在其答案中提出的TextView + ImageView布局.

在我的用例中,我只是将Button对象放入菜单中,然后依靠onButtonClick按钮的处理程序来响应事件 - 有效地在需要在包含菜单的活动中处理它们.

(很棒的问题,顺便说一下.谢谢!)

  • 我想补充一点,当我们改变菜单上的视图时,当用户点击菜单项时,不会调用onOptionsItemSelected回调,因此我们必须向我们添加onClickListener customView. (4认同)

akh*_*707 5

经过测试,像魅力一样工作:)

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_feedback_filter, menu);

    for (int i = 0; i < menu.size(); i++) {
        MenuItem mi = menu.getItem(i);
        //for aapplying a font to subMenu ...
        SubMenu subMenu = mi.getSubMenu();
        if (subMenu != null && subMenu.size() > 0) {
            for (int j = 0; j < subMenu.size(); j++) {
                MenuItem subMenuItem = subMenu.getItem(j);
                applyFontToMenuItem(subMenuItem, typeface);
            }
        }
        //the method we have create in activity
        applyFontToMenuItem(mi, typeface);
    }

    return super.onCreateOptionsMenu(menu);
}



private void applyFontToMenuItem(MenuItem mi, Typeface font) {
    SpannableString mNewTitle = new SpannableString(mi.getTitle());
    mNewTitle.setSpan(new CustomTypefaceSpan("", font), 0, mNewTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    mi.setTitle(mNewTitle);
}
Run Code Online (Sandbox Code Playgroud)

自定义跨度类

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


R4j*_*R4j 1

我认为Android不支持选项菜单的自定义。但你可以尝试另一种方式:http://www.codeproject.com/Articles/173121/Android-Menus-My-Way
这样,实际上菜单项是一个textview和imageview,所以你可以轻松地改变字体,颜色。 ..

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:padding="4dip"
android:clickable="true"
android:background="@drawable/custom_menu_selector">
<ImageView
    android:id="@+id/custom_menu_item_icon"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:paddingBottom="2dip"
    android:paddingTop="2dip"/>
<TextView
    android:id="@+id/custom_menu_item_caption"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#ffffff"
    android:textSize="12sp"
    android:gravity="center"/>
Run Code Online (Sandbox Code Playgroud)