我有以下RecyclerView列表:
我只希望我的测试单击右侧的复选框,而不是整个项目。 这是我尝试过的:
onView(withId(R.id.recycler_view))
.perform(actionOnViewHolder<ViewHolder>(matcher = { vh ->
if (vh == null) return@actionOnViewHolder false
if (vh.position == no) {
// v1
(vh.itemView as ViewGroup).findViewById<View>(R.id.checkbox)?.performClick()
// v2
(vh.itemView as ViewGroup).getChildAt(2)?.performClick()
}
return@actionOnViewHolder false
}))
以及一些辅助方法/类:
inline fun <reified VH : RecyclerView.ViewHolder> actionOnViewHolder(
noinline matcher: (VH?) -> Boolean): RecyclerViewActions.PositionableRecyclerViewAction {
return RecyclerViewActions.actionOnHolderItem(
RecyclerViewViewHolderMatcher(VH::class.java, matcher), ViewActions.click())
}
class RecyclerViewViewHolderMatcher<VH : RecyclerView.ViewHolder>(
clazz: Class<VH>,
private val matcher: (VH?) -> Boolean) : BoundedMatcher<RecyclerView.ViewHolder, VH>(clazz) {
override fun describeTo(description: Description?) { }
override fun matchesSafely(item: VH): Boolean = matcher(item)
}
V1:(vh.itemView as ViewGroup).findViewById<View>(R.id.checkbox)
返回null,尽管在调试器中我可以看到3个孩子的视图,最后一个孩子的ID为:checkbox
。
V2:(vh.itemView as ViewGroup).getChildAt(2)
返回视图,但是稍后会发生单击。
此外,我总是从false
返回actionOnViewHolder
,因为我不想click()
或整个ViewHolder上的其他任何东西。
有什么办法可以更好地做到这一点?
答案 0 :(得分:0)
使用辅助方法添加新类:
object EspressoMatchers {
fun atPositionOnView(mRecyclerViewId: Int, position: Int, targetViewId: Int): Matcher<View> {
return object : TypeSafeMatcher<View>() {
var resources: Resources? = null
var childView: View? = null
override fun describeTo(description: Description) {
val id = targetViewId
var idDescription = Integer.toString(id)
if (this.resources != null) {
try {
idDescription = this.resources!!.getResourceName(id)
} catch (var4: Resources.NotFoundException) {
idDescription = String.format("%s (resource name not found)", id)
}
}
description.appendText("with id: $idDescription")
}
public override fun matchesSafely(view: View): Boolean {
this.resources = view.resources
if (childView == null) {
val recyclerView: RecyclerView = if (view.rootView.findViewById<View>(mRecyclerViewId) is RecyclerView) {
view.rootView.findViewById<View>(mRecyclerViewId) as RecyclerView
} else {
//todo need only if you want acces to recyclerView in custom views
}
childView = recyclerView.findViewHolderForAdapterPosition(position)!!.itemView
}
val targetView = childView!!.findViewById<View>(targetViewId)
return view === targetView
}
}
}}
创建单元格包装器
open class BaseCell(val listId: Int, val position: Int) {
public fun tap(id: Int) {
onView(atPositionOnView(listId, position, id)).perform(click())
}
}
然后我们可以在测试中使用它
val cell = BaseCell(R.id.recyclerViewId, 0)
cell.tap(R.id.checkBoxId)