1

如何自定义弹出菜单以更改每个弹出菜单中每个选项的颜色/字体/样式?

4

3 回答 3

1

我在自定义 PopupMenu 字体和文本大小时遇到​​了同样的问题。最后我使用了反射。它可用于任何弹出菜单项的自定义。android支持中菜单项的资源布局在android.support.v7.internal.view.menu.MenuPopupHelper中定义,其字段名称为“ITEM_LAYOUT”,声明为static final;它的值等于“R.layout.abc_popup_menu_item_layout” 我在 Grepcode 中找到布局文件并将其复制到我的项目布局目录中。我将其命名为 popup_menu_item_layout.xml。我的弹出菜单项布局在这里

<?xml version="1.0" encoding="utf-8"?>
<mypackage.PopupMenuItemView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?attr/dropdownListPreferredItemHeight"
    android:minWidth="196dip"
    android:paddingRight="16dip">

<!-- Icon will be inserted here. -->

<!-- The title and summary have some gap between them, and this 'group' should be centered vertically. -->
<RelativeLayout
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="16dip"
        android:duplicateParentState="true">

    <TextView
            android:id="@+id/title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:textAppearance="?attr/textAppearanceLargePopupMenu"
            android:singleLine="true"
            android:duplicateParentState="true"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"/>

    <TextView
            android:id="@+id/shortcut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/title"
            android:layout_alignParentLeft="true"
            android:textAppearance="?attr/textAppearanceSmallPopupMenu"
            android:singleLine="true"
            android:duplicateParentState="true"/>

</RelativeLayout>

<!-- Checkbox, and/or radio button will be inserted here. -->

然后创建自定义类 PopupMenuItemView:

public class PopupMenuItemView extends android.support.v7.internal.view.menu.ListMenuItemView {

public PopupMenuItemView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public PopupMenuItemView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    applyTypefaceToAll(this, your_typeface);
    TypefaceUtils.applyTextSizeToAll(this, your_textsize);
}

public static void applyTypefaceToAll(View view, Typeface typeface) {
    if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup) view;
        for (int childIndex = 0; childIndex < viewGroup.getChildCount(); childIndex++)
            applyTypefaceToAll(viewGroup.getChildAt(childIndex), typeface);
    } else if (view instanceof TextView) {
        TextView textView = (TextView) view;
        textView.setTypeface(typeface);
        textView.setPaintFlags(textView.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
    }
}

public static void applyTextSizeToAll(View view, float size) {
    if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup) view;
        for (int childIndex = 0; childIndex < viewGroup.getChildCount(); childIndex++)
            applyTextSizeToAll(viewGroup.getChildAt(childIndex), size);
    } else if (view instanceof TextView) {
        TextView textView = (TextView) view;
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
        textView.setPaintFlags(textView.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
    }
}
}

最后通过反射替换菜单项的布局资源id;在您的主要活动 onCreate 方法或您的应用程序 onCreate 方法中的一些地方:

    try {
         setFinalStatic(MenuPopupHelper.class.getDeclaredField("ITEM_LAYOUT"),
                R.layout.popup_menu_item_layout);
    } catch (Exception e) {
        e.printStackTrace();
    }

    public static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);

    try {
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    }catch (Exception e) {
        e.printStackTrace();
    }

    field.set(null, newValue);
}
于 2015-09-02T08:00:52.660 回答
0

您可以将弹出窗口视为视图,甚至可以视为单独的活动(使用透明背景,查看 android 上的主题选项)

然后,当您想要显示弹出窗口时,您可以从应用程序中的任何活动启动它,它始终具有相同的 bg 和按钮样式,您只会为其提供实际数据。

例如:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:background="@drawable/bg_popup"
android:layout_gravity="center"
android:alpha="0.8"
android:visibility="visible"
android:id="@+id/generic_popup2_container"
android:layout_height="300dp">
<TextView
    android:id="@+id/generic_popup2_tv_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/white"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="20dp"
    android:layout_alignParentTop="true"
    android:text="header"
    android:gravity="center"
    android:textSize="28sp" />
<TextView
    android:id="@+id/generic_popup2_tv_inner_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/white"
    android:text="content"
    android:textSize="16sp"
    android:gravity="center"
    android:layout_marginTop="20dp"
    android:layout_below="@id/generic_popup2_tv_title"
    android:layout_centerHorizontal="true" />
<LinearLayout
    android:id="@+id/generic_popup_2_buttons_layout"
    android:layout_centerHorizontal="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="20dp"
    android:orientation="horizontal">
    <Button
        android:id="@+id/layout_2_generic_popup_btn_action1"
        android:layout_width="115dp"
        android:layout_height="35dp"
        android:textColor="@color/white"
        android:layout_marginBottom="10dp"
        android:textSize="12sp"
        android:layout_marginRight="10dp"
        android:background="@drawable/popup_btn_blue" />
    <Button
        android:id="@+id/layout_2_generic_popup_btn_action2"
        android:layout_width="115dp"
        android:layout_height="35dp"
        android:textColor="@color/white"
        android:textSize="12sp"
        android:background="@drawable/popup_btn_blue" />
</LinearLayout>

于 2013-08-27T10:35:58.357 回答
0

创建一个弹出窗口并根据需要对其进行自定义。
以下是一些有用的链接:
how-to-create-popup-window-in-android
您还可以查看快速操作对话框

于 2013-08-27T11:02:52.090 回答