【问题标题】:Custom PopupMenu (layout)自定义 PopupMenu(布局)
【发布时间】:2014-10-10 18:49:13
【问题描述】:

我正在尝试升级我的 PopupMenu,以便它带有图标和自定义样式。
我为它创建了一个新布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
        android:id="@+id/layout_sharea"
        android:background="@drawable/share"
        android:paddingLeft="10.0dip"
        android:paddingRight="10.0dip"
        android:layout_width="wrap_content"
        android:layout_height="50.0dip"
        android:onClick="share">
        <TextView
            android:id="@+id/sharetexta"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/share"
            android:drawableLeft="@drawable/share_button"
            android:drawablePadding="10.0dip"
            android:layout_centerVertical="true" />
     </RelativeLayout>
     <RelativeLayout
        android:id="@+id/layout_shareb"
        android:background="@drawable/share"
        android:paddingLeft="10.0dip"
        android:paddingRight="10.0dip"
        android:layout_width="wrap_content"
        android:layout_height="50.0dip"
        android:layout_below="@+id/layout_sharea"
        android:onClick="share">
        <TextView
            android:id="@+id/sharetextb"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/share"
            android:drawableLeft="@drawable/share_button"
            android:drawablePadding="10.0dip"
            android:layout_centerVertical="true" />
     </RelativeLayout>
</RelativeLayout>

我希望像这张图片一样自定义 PopupMenu(成为这种布局)

【问题讨论】:

  • 引用此answer 以获得更简单的自定义文本颜色/背景修复。

标签: android layout drop-down-menu android-custom-view popupmenu


【解决方案1】:

PopupMenu 用于显示Menus,并且确实没有自定义菜单项外观的好方法。如果你想要更灵活的东西,你的答案是ListPopupWindow

private static final String TITLE = "title";
private static final String ICON = "icon";

private List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();

// Use this to add items to the list that the ListPopupWindow will use
private void addItem(String title, int iconResourceId) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put(TITLE, title);
    map.put(ICON, iconResourceId);
    data.add(map);
}

// Call this when you want to show the ListPopupWindow
private void showListMenu(View anchor) {
    ListPopupWindow popupWindow = new ListPopupWindow(this);

    ListAdapter adapter = new SimpleAdapter(
            this,
            data,
            android.R.layout.activity_list_item, // You may want to use your own cool layout
            new String[] {TITLE, ICON}, // These are just the keys that the data uses
            new int[] {android.R.id.text1, android.R.id.icon}); // The view ids to map the data to


    popupWindow.setAnchorView(anchor);
    popupWindow.setAdapter(adapter);
    popupWindow.setWidth(400); // note: don't use pixels, use a dimen resource
    popupWindow.setOnItemClickListener(myListener); // the callback for when a list item is selected
    popupWindow.show();
}

【讨论】:

【解决方案2】:

这是我通过自定义适配器自定义 ListPopupWindow 的演示

Model

public class ListPopupItem {
    private String title;
    private int imageRes;

    public ListPopupItem(String title, int imageRes) {
        this.title = title;
        this.imageRes = imageRes;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getImageRes() {
        return imageRes;
    }
}

ListAdapter

public class ListPopupWindowAdapter extends BaseAdapter {
    private List<ListPopupItem> items;

    public ListPopupWindowAdapter(List<ListPopupItem> items) {
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public ListPopupItem getItem(int i) {
        return items.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_popup, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.tvTitle.setText(getItem(position).getTitle());
        holder.ivImage.setImageResource(getItem(position).getImageRes());
        return convertView;
    }

    static class ViewHolder {
        TextView tvTitle;
        ImageView ivImage;

        ViewHolder(View view) {
            tvTitle = view.findViewById(R.id.text);
            ivImage = view.findViewById(R.id.image);
        }
    }
}

item_list_popup.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="ContentDescription"
        tools:src="@mipmap/ic_launcher"
        />
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        tools:text="Title"
        />
</LinearLayout>

最后显示ListPopupWindow
(In this demo, I show MATCH_PARENT popup here, you can show a specific with for popup (eg: 100px, 200px,...) If you set popup width = WRAP_CONTENT, popup width will equals ANCHOR width)

private void showListPopupWindow(View anchor) {
    List<ListPopupItem> listPopupItems = new ArrayList<>();
    listPopupItems.add(new ListPopupItem("Menu 1", R.mipmap.ic_launcher));
    listPopupItems.add(new ListPopupItem("Menu 2", R.mipmap.ic_launcher));
    listPopupItems.add(new ListPopupItem("Menu 3", R.mipmap.ic_launcher));

    final ListPopupWindow listPopupWindow =
            createListPopupWindow(anchor, ViewGroup.LayoutParams.MATCH_PARENT, listPopupItems);
    listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listPopupWindow.dismiss();
            Toast.makeText(MainActivity.this, "clicked at " + position, Toast.LENGTH_SHORT)
                    .show();
        }
    });
    listPopupWindow.show();
}

private ListPopupWindow createListPopupWindow(View anchor, int width,
        List<ListPopupItem> items) {
    final ListPopupWindow popup = new ListPopupWindow(this);
    ListAdapter adapter = new ListPopupWindowAdapter(items);
    popup.setAnchorView(anchor);
    popup.setWidth(width);
    popup.setAdapter(adapter);
    return popup;
}

使用示例

button.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
            showListPopupWindow(view);
       }
});

DEMO

【讨论】:

  • 要使 ListPopupWindow 显示在屏幕键盘上方,请添加 listPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);。此外,可能还有一种自定义窗口动画的方法,如下所述:stackoverflow.com/questions/12636101/how-to-style-popupmenu
  • @Mr-IDE 感谢您在使用 ListPopupWindow 和软键盘时分享解决方案
  • 非常感谢您提供这个详细的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 2015-04-05
  • 2017-10-15
  • 2016-06-28
  • 2015-08-11
  • 2017-01-23
  • 1970-01-01
相关资源
最近更新 更多