Android 菜单项自定义布局

19

当我在操作栏中的动作按钮上单击时,会弹出一个PopupMenu。我希望我的PopupMenu中的MenuItem具有自定义布局,如下所示:

layout/menu_item_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/menuItemLayout"

    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/imageViewMenuItem"
        android:layout_width="20dip"
        android:layout_height="20dip"
        android:src="@drawable/abc_list_focused_holo" />

    <TextView
        android:id="@+id/textViewMenuItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextViewMenuItem" />

</LinearLayout>

这是 PopUpMenu 的 XML 文件:

menu/pop_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       tools:context="apparound.actiobarpopupstylefacebook.Main" >

    <item
        android:id="@+id/popupItem"
        android:showAsAction="ifRoom"/>
</menu>

我的活动代码如下:

public void showPopup(int idR){
View menuItemView = findViewById(idR);
PopupMenu popup = new PopupMenu(this, menuItemView);
MenuInflater inflate = popup.getMenuInflater();
inflate.inflate(R.menu.pop_menu, popup.getMenu());
MenuItem menuItem= popup.getMenu().findItem(R.id.popupItem);
menuItem.setActionView(R.layout.menu_item_layout);
popup.show();
}

但是当弹出菜单出现时,菜单项为空。我使用setActionView()方法错了吗?谢谢。

3个回答

35

对于自定义布局,您不能使用菜单,一种替代选项是PopupWindow

PopupWindow popupwindow_obj = popupDisplay();
popupwindow_obj.showAsDropDown(clickbtn, -40, 18); // where u want show on view click event popupwindow.showAsDropDown(view, x, y);

public PopupWindow popupDisplay() 
{ 

    final PopupWindow popupWindow = new PopupWindow(this);

    // inflate your layout or dynamically add view
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    View view = inflater.inflate(R.layout.mylayout, null);

    Button item = (Button) view.findViewById(R.id.button1);

    popupWindow.setFocusable(true);
    popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
    popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
    popupWindow.setContentView(view);

    return popupWindow;
}

请在res/layout文件夹中创建名为"my_layout.xml"的XML文件。

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Window test" />
</LinearLayout>

2
弹出窗口上有黑色边框。 - Jemshit Iskenderov
2
使用 popupWindow.setBackgroundDrawable(null); 进行修复。 - Jemshit Iskenderov
我完全不理解这个。那么为什么还要存在PopupMenu?如果您不能将其用于自定义布局,并且只能在主布局中使用它,那么为什么不在主布局中使用ActionBar呢?我看不出PopupMenu的任何用途。 - Daniel Viglione
点击"Items"怎么样?我们只需为它们设置点击监听器,就像简单的按钮一样,对吗?有更简单的方法吗? - inverted_index
先生,您好。我想问一下如何关闭我创建的弹出窗口,因为在其他设备上,当我在窗口外单击时,窗口本身没有关闭。但是非常感谢您给我的答案,我点了赞 :) - Android Mediocre
显示剩余2条评论

0

最终 PopupWindow popupWindow = new PopupWindow(); // 填充您的布局或动态添加视图

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

View view = inflater.inflate(R.layout.alert_reply_chat,null); 
popupWindow.setFocusable(true); 
popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); 
popupWindow.setHeight(180); popupWindow.setBackgroundDrawable(null); 
popupWindow.setClippingEnabled(false); popupWindow.setTouchable(true); 
popupWindow.setContentView(view); return popupWindow; 

//以上是我检查过的可用代码


0

默认情况下,PopupMenu(及其项目)的布局不能自定义。在下面的解决方案中,我创建了一个具有水平布局的PopupMenu。在这种情况下,我使用TextView作为可点击项,但您可以轻松地将它们替换为按钮。您可以随心所欲地自定义菜单项。

1- 自定义PopupMenu类:

public class PopupMenuCustomLayout {
    private PopupMenuCustomOnClickListener onClickListener;
    private Context context;
    private PopupWindow popupWindow;
    private int rLayoutId;
    private View popupView;

    public PopupMenuCustomLayout(Context context, int rLayoutId, PopupMenuCustomOnClickListener onClickListener) {
        this.context = context;
        this.onClickListener = onClickListener;
        this.rLayoutId = rLayoutId;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
        popupView = inflater.inflate(rLayoutId, null);
        int width = LinearLayout.LayoutParams.WRAP_CONTENT;
        int height = LinearLayout.LayoutParams.WRAP_CONTENT;
        boolean focusable = true;
        popupWindow = new PopupWindow(popupView, width, height, focusable);
        popupWindow.setElevation(10);

        LinearLayout linearLayout = (LinearLayout) popupView;
        for (int i = 0; i < linearLayout.getChildCount(); i++) {
            View v = linearLayout.getChildAt(i);
            v.setOnClickListener( v1 -> { onClickListener.onClick( v1.getId()); popupWindow.dismiss(); });
        }
    }
    public void setAnimationStyle( int animationStyle) {
        popupWindow.setAnimationStyle(animationStyle);
    }
    public void show() {
        popupWindow.showAtLocation( popupView, Gravity.CENTER, 0, 0);
    }

    public void show( View anchorView, int gravity, int offsetX, int offsetY) {
        popupWindow.showAsDropDown( anchorView, 0, -2 * (anchorView.getHeight()));
    }

    public interface PopupMenuCustomOnClickListener {
        public void onClick(int menuItemId);
    }
}

2 - 您的自定义布局,例如具有水平布局的LinearLayout。在这种情况下,我使用一个简单的LinearLayout和TextView项。您也可以使用按钮等。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/popup_menu_custom_item_a"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="A"
        android:textAppearance="?android:textAppearanceMedium" />
    <TextView
        android:id="@+id/popup_menu_custom_item_b"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:text="B"
        android:textAppearance="?android:textAppearanceMedium" />
    // ...
</LinearLayout>

3 - 使用自定义弹出菜单,就像使用普通的弹出菜单一样。

PopupMenuCustomLayout popupMenu = new PopupMenuCustomLayout(
        MainActivity.mainActivity, R.layout.popup_menu_custom_layout,
        new PopupMenuCustomLayout.PopupMenuCustomOnClickListener() {
            @Override
            public void onClick(int itemId) {
                // log statement: "Clicked on: " + itemId
                switch (itemId) {
                    case R.id.popup_menu_custom_item_a:
                        // log statement: "Item A was clicked!"
                        break;
                }
            }
        });
// Method 1: popupMenu.show();
// Method 2: via an anchor view: 
popupMenu.show( anchorView, Gravity.CENTER, 0, 0);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接