不幸的是,你的理想情况无法实现。这是由于支持库的构建。
让我们从PopupMenu https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/widget/PopupMenu.java#48,其中引用了MenuPopupHelper https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java#58,其中参考了MenuPopup https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/MenuPopup.java。这是一个扩展的抽象类。经过StandardMenuPopup https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java。它有参考MenuAdapter https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java#92。如果你查看第 92 行MenuAdapter
你会看到这一行:
itemView.initialize(getItem(position), 0);
这是关键的方法调用。它可以被调用ActionMenuItemView https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java or ListMenuItemView https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java。他们的实现有所不同,即id 附加到 ActionMenuItemView https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java#132, and 未附加到 ListMenuItemView https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java#102
而且,MenuAdapter.getItemId(int position) https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java#80仅返回position
。菜单项的 id 在溢出菜单中丢失。
但是,您的代码可以简化为一行。定义一个函数:
public static Matcher<View> withMenuIdOrText(@IdRes int id, @StringRes int menuText) {
Matcher<View> matcher = withId(id);
try {
onView(matcher).check(matches(isDisplayed()));
return matcher;
} catch (Exception NoMatchingViewException) {
openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getInstrumentation().getTargetContext());
return withText(menuText);
}
}
Usage:
onView(withMenuIdOrText(R.id.menu_id, R.string.menu_text)).perform(click());