如何为弹出菜单项设置id,找到视图ID?

and*_*per 5 android popupmenu menuitem

背景

out自动测试使用视图'id来点击它们,所以我们尽可能添加id.

问题

对于弹出菜单,有时需要动态填充它们,但正如我发现的那样,即使我为每个项目添加了id,也找不到id,也无法使用.即使使用DDMS的功能"用于UI自动机的转储视图层次结构",也会显示弹出菜单中的任何视图都没有ID.

我试过的

这是我使用的示例代码,尝试为单个菜单项设置id.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    View v=findViewById(R.id.button);
    v.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(final View v) {
            PopupMenu popupMenu = new PopupMenu(MainActivity.this, v);
            final Menu menu = popupMenu.getMenu();
            menu.add(0, R.id.myMenuItem, 0, R.string.app_name).setOnMenuItemClickListener(new OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(final MenuItem item) {
                    return false;
                }
            }) ;
            popupMenu.show();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

请注意,id在"ids.xml"文件中声明,如下所示:

<item name="myMenuItem" type="id"/>
Run Code Online (Sandbox Code Playgroud)

这就是DDMS工具向我展示的内容:

在此输入图像描述

这个问题

为什么这段代码没有按预期工作(意味着菜单项视图有id)?我该怎么做才能使其中的视图具有ID?为动态创建的菜单项添加ID的正确方法是什么?

Lig*_*ind 1

好吧,这绝不是问题中描述的问题的答案。将其视为替换的替代方案PopupMenu,以实现所要求的目标。

PopupMenu

在深入研究其文档PopupMenu及其源代码后,我终于明白这PopupMenu不是一个允许定制的实现(我为评论中的误解向 PO 道歉)。

替代

作为替代方案,aListPopupWindow是创建弹出菜单的首选,原因如下:

  1. PopupMenu它与-共享同一个父级ListView
  2. 它很灵活,允许Adapter使用自定义布局来定义自定义。
  3. 它还允许像PopupMenu以前那样进行运行时创建,并允许将资源 ID 附加到项目视图。

执行

首先,让我们为弹出项 ( popup_item_view.xml) 定义一个自定义布局。

<?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="match_parent"
    android:orientation="vertical"
    android:padding="16dp">
    <TextView
        android:id="@+id/popup_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

接下来,定义一个自定义Adapter类来操作布局。

package com.example.popupmenu;

import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class PopupAdapter extends BaseAdapter {
    public static class Item {
        public final int id;
        public final String title;

        public Item(int id, @NonNull String title) {
            this.id = id;
            this.title = title;
        }
    }

    private List<Item> mItemList = new ArrayList<>();

    public PopupAdapter(@NonNull Item[] items) {
        mItemList.addAll(Arrays.asList(items));
    }

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

    @Override
    public Item getItem(int position) {
        return mItemList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final Item item = getItem(position);
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            convertView = inflater.inflate(R.layout.popup_item_view, parent, false);
        }
        convertView.setId(item.id);
        TextView titleView = (TextView) convertView.findViewById(R.id.popup_text);
        titleView.setText(item.title);
        return convertView;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,PopupMenu用此替换代码。

PopupAdapter.Item[] items = {
    new PopupAdapter.Item(R.id.popup_item_1, "item 1"),
    new PopupAdapter.Item(R.id.popup_item_2, "item 2")
};

ListPopupWindow popup = new ListPopupWindow(MainActivity.this);
popup.setAnchorView(view);
popup.setAdapter(new PopupAdapter(items));
popup.setModal(true);
popup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        // do something
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
       // do something
    }
});
popup.show();
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。