Android 如何设置弹出菜单项的id,作为视图id? 背景
Out自动测试使用视图的ID来点击它们,所以我们尽可能地添加ID 问题 对于弹出菜单,有时需要动态填充它们,但正如我所发现的,即使我为每个项目添加了id,也找不到id,也无法使用。即使使用DDMS的功能“dump view hierarchy for UI automator”也表明弹出菜单中没有视图具有id 我试过的 这是我用来尝试为单个菜单项设置id的示例代码Android 如何设置弹出菜单项的id,作为视图id? 背景,android,menuitem,popupmenu,Android,Menuitem,Popupmenu,Out自动测试使用视图的ID来点击它们,所以我们尽可能地添加ID 问题 对于弹出菜单,有时需要动态填充它们,但正如我所发现的,即使我为每个项目添加了id,也找不到id,也无法使用。即使使用DDMS的功能“dump view hierarchy for UI automator”也表明弹出菜单中没有视图具有id 我试过的 这是我用来尝试为单个菜单项设置id的示例代码 @Override protected void onCreate(Bundle savedInstanceState) {
@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();
}
});
}
请注意,id在“ids.xml”文件中声明,如下所示:
<item name="myMenuItem" type="id"/>
这是DDMS工具向我展示的:
问题
为什么这段代码不能按预期工作(意味着有菜单项视图的id)?如何使其中的视图具有ID?为动态创建的菜单项添加ID的正确方法是什么 好吧,这绝不是问题中描述的问题的答案。将其视为替换
PopupMenu
以实现要求的功能的替代方案
否弹出菜单
在翻阅了PopupMenu
的文档及其源代码后,我终于明白PopupMenu
不是一个允许定制的实现(我为评论中的误解向PO道歉)
替代方案
另一种选择是使用ListPopupWindow
创建弹出菜单,原因如下:
弹出菜单
-列表视图
共享同一父级适配器
PopupMenu
does,并允许将资源id附加到项目视图popup\u item\u view.xml
)
最后,将弹出菜单
代码替换为以下内容
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();
PopupAdapter.Item[]项={
新的PopupAdapter.Item(R.id.popup_Item_1,“Item 1”),
新的PopupAdapter.Item(R.id.popup_Item_2,“Item 2”)
};
ListPopupWindow popup=新建ListPopupWindow(MainActivity.this);
弹出.setAnchorView(视图);
setAdapter(新的PopupAdapter(项目));
popup.setModal(true);
popup.setOnItemSelectedListener(新的AdapterView.OnItemSelectedListener(){
@凌驾
已选择公共视图(AdapterView父视图、视图视图、整型位置、长id){
//做点什么
}
@凌驾
未选择公共无效(AdapterView父级){
//做点什么
}
});
popup.show();
希望这能有所帮助。你能详细说明一下“没有按预期工作”吗?@haike00,正如我所写的:它没有id,即使我已经将它设置为有id。我现在会添加更好的代码和屏幕快照。恐怕我还是不明白你想做什么。据我所知,您正试图将
R.id.myMenuItem
设置为MenuItem
的id。因此,在OnMenuItemClickListener()
侦听器中,当您执行item.getItemId()
时,您将能够检索到与R.id.myMenuItem
等效的id。这不是你想要的吗?@haike00正如我在“背景”部分中所写,我需要视图本身具有此id,以便自动测试能够找到视图并单击它。这适用于工具栏菜单项,但不适用于弹出菜单。我不需要应用程序本身的id,因为我已经有了对菜单项的引用。我需要它来进行自动测试。我刚刚做了一个测试,即使是工具栏
也不会给我一个正确的资源id。无论如何,您传递到菜单的第二个参数。添加(0,x,0,0)
是针对项目id的。如果需要,您必须强制循环菜单项视图,并将项目ID设置为其视图ID。另一种选择是考虑使用索引ID来实现您想要做的。这很有趣。它是否还能够选择将弹出窗口放在何处(在视图的顶部或下方)?不管怎样,希望能尽快查出来,然后勾选答案。现在,请使用+1.:)我认为它是在运行时决定的(通过ListPopupWindow
),如果它觉得在锚定的视图下没有足够的空间,它只会在上面绘制它。试试看好的,您可以使用setDropDownGravity(gravity)
进行设置。不,不能使用setDropDownGravity(gravity)
进行设置。我不确定它是否有效。我的意思是这对这:。一个在目标视图的下方,一个在目标视图的顶部。
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;
}
}
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();