如何用Espresso点击锚定在ListView项上的PopupMenu菜单项?
我有一个通过点击ListView内按钮触发的PopupMenu,需要通过ID点击其中的菜单项。
我的测试代码如下:
val item = onData(anything()).inAdapterView(withId(R.id.profiles_list)).atPosition(index) val menuButton = item.onChildView(withId(R.id.options_button)) menuButton.perform(click()) // 这行代码可以打开锚定在menuButton上的弹窗
菜单的创建代码:
val popup = PopupMenu(context, menuButton) popup.setOnMenuItemClickListener { when (it.itemId) { R.id.profile_rename -> { // 执行对应操作 true } else -> false } } popup.menuInflater.inflate(R.menu.list_item_profile, popup.menu) popup.show()
我尝试用isPlatformPopup()定位弹窗,但没成功:
menuButton.inRoot(isPlatformPopup()).onChildView(withId(R.id.profile_rename)).perform(click())
解决方法
你之前的代码问题出在定位逻辑的链式调用错误:menuButton属于原ListView所在的窗口,而PopupMenu是系统级别的独立窗口,不能从menuButton的ViewInteraction链上直接调用inRoot()切换查找范围。
正确的做法是直接用onView()定位菜单项,并通过inRoot(isPlatformPopup())指定查找系统弹窗的根View:
val item = onData(anything()).inAdapterView(withId(R.id.profiles_list)).atPosition(index) val menuButton = item.onChildView(withId(R.id.options_button)) menuButton.perform(click()) // 打开弹窗 // 可选:等待弹窗完全渲染,避免因加载速度问题导致查找失败 Thread.sleep(300) // 定位并点击目标菜单项 onView(withId(R.id.profile_rename)) .inRoot(isPlatformPopup()) .perform(click())
补充说明
- 如果通过ID找不到菜单项,可以尝试用文本定位(前提是菜单文本固定):
onView(withText("重命名")) .inRoot(isPlatformPopup()) .perform(click())
- 若测试稳定性要求较高,建议使用IdlingResource替代
Thread.sleep(),等待PopupMenu完全显示后再执行点击操作,避免因设备性能差异导致的测试失败。 - 确保
R.id.profile_rename在菜单布局文件list_item_profile.xml中正确定义,且无ID冲突。
内容的提问来源于stack exchange,提问作者cj-
相关产品推荐
相关产品推荐

