Android MenuItem 自定义布局

Posted

技术标签:

【中文标题】Android MenuItem 自定义布局【英文标题】:Android MenuItem Custom Layout 【发布时间】:2014-06-25 16:15:46 【问题描述】:

我有一个PopupMenu,当我单击操作栏中的操作按钮时会出现。 我希望我的 PopupMenu 中的 MenuItem 具有这样的自定义布局:

布局/menu_item_layout.xml

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

    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/imageViewMenuItem"
        android:layout_
        android:layout_
        android:src="@drawable/abc_list_focused_holo" />

    <TextView
        android:id="@+id/textViewMenuItem"
        android:layout_
        android:layout_
        android:text="TextViewMenuItem" />

</LinearLayout>

这是 PopUpMenu 的 xml:

菜单/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() 方法我错了吗? 谢谢。

【问题讨论】:

【参考方案1】:

对于不能使用菜单的自定义布局,一个替代选项是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;

在名为 my layout.xml 的 res/layout 文件夹中创建此 XML 文件

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="horizontal" >

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

【讨论】:

20+问答之间,你的答案是最好的。你必须给 +500 或 +1000 票。 弹窗有黑边 popupWindow.setBackgroundDrawable(null);修复 我一点也不明白。那么为什么 PopupMenu 还存在呢?如果不能用于自定义布局,只能在主布局中使用,那为什么不直接在主布局中使用 ActionBar 呢?我认为弹出菜单没有任何意义。 什么是Button item = (Button) view.findViewById(R.id.button1);我没有看到它在任何地方使用。【参考方案2】:

最终弹出窗口 popupWindow = new PopupWindow(); // 膨胀你的布局或动态添加视图 LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 查看视图 = 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);返回弹出窗口; //上面是我检查过的工作代码

【讨论】:

【参考方案3】:

默认情况下,无法自定义 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 - 您的自定义布局,例如带有水平布局的线性布局。在这种情况下,我使用带有 TextView 项目的简单 LinearLayout。你可以使用按钮等。

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

3 - 像普通 PopupMenu 一样使用自定义 PopupMenu。

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

【讨论】:

以上是关于Android MenuItem 自定义布局的主要内容,如果未能解决你的问题,请参考以下文章

[WPF 自定义控件]在MenuItem上使用RadioButton

Community Cloud零基础学习Builder创建自定义的布局

[Android] 自定义 Dialog 布局设置固定宽高无效

如何在 Android 中定义自定义(复合)布局?

Android RecycleView自定义布局的使用

Android问题:自定义的布局类,一次Touch,两次调用onTouchEvent()方法,为啥?