Kakao/Kaspresso中多ViewType RecyclerView点击问题求助
基于Kaspresso/Kakao实现多ViewType RecyclerView的首个普通项点击
我在使用Kakao进行UI测试时,遇到了多ViewType RecyclerView的操作问题:该RecyclerView作为自动补全组件,包含两种ViewType:
- 普通结果项(布局ID为
auto_completer_item_root) - 周边搜索特殊项(布局ID为
gps_search_item_root)
我的需求是点击RecyclerView中第一个属于普通类型的项,但当前列表的首个项是上述特殊类型。
对应的视图布局代码
普通结果项布局
<androidx.constraintlayout.widget.ConstraintLayout ... android:id="@+id/auto_completer_item_root" ...> <TextView android:id="@+id/destination_title" ... /> ... </androidx.constraintlayout.widget.ConstraintLayout>
周边搜索特殊项布局
<androidx.constraintlayout.widget.ConstraintLayout ... android:id="@+id/gps_search_item_root" ...> <TextView android:id="@+id/gps_title" ... /> ... </androidx.constraintlayout.widget.ConstraintLayout>
已实现的Screen对象代码
class AutoCompleterScreen : KScreen<AutoCompleterScreen>() { override val layoutId: Int? = null override val viewClass: Class<*>? = null val resultList = KRecyclerView( builder = { withId(R.id.destinationList) }, itemTypeBuilder = { itemType(::GpsSearch) itemType(::AutoCompleterResult) } ) internal class AutoCompleterResult(parent: Matcher<View>) : KRecyclerItem<AutoCompleterResult>(parent) { val title: KTextView = KTextView(parent) { withId(R.id.destination_title) } } internal class GpsSearch(parent: Matcher<View>) : KRecyclerItem<GpsSearch>(parent) { val title: KTextView = KTextView(parent) { withId(R.id.gps_title) } } }
尝试过的无效写法
- 原本预期生效,但实际无响应:
onScreen<AutoCompleterScreen> { resultList { firstChild<AutoCompleterScreen.AutoCompleterResult> { title { click() } } } }
- 偶然成功一次但无法复现(推测和应用未全新安装有关):
onScreen<AutoCompleterScreen> { resultList { childWith<AutoCompleterScreen.AutoCompleterResult> { withId(R.id.auto_completer_item_root) isFirst() } perform { click() } } }
可正常工作的Espresso实现
我已经写出了可以正常运行的Espresso代码,但希望基于Kaspresso框架实现相同逻辑:
onView(withId(R.id.destinationList)) .perform(actionOnFirstItemWithId(R.id.auto_completer_item_root, click()))
对应的辅助方法:
fun actionOnFirstItemWithId(@IdRes viewId: Int, action: ViewAction): ViewAction { return object : ViewAction { override fun getConstraints(): Matcher<View> { return Matchers.allOf(ViewMatchers.isAssignableFrom(RecyclerView::class.java), ViewMatchers.isDisplayed()) } override fun getDescription(): String { return "Perform action on the first item that has a view with the given ID." } override fun perform(uiController: UiController, view: View) { val recyclerView = view as RecyclerView for (i in 0 until recyclerView.adapter!!.itemCount) { uiController.loopMainThreadForAtLeast(500) val viewHolder = recyclerView.findViewHolderForAdapterPosition(i) if (viewHolder?.itemView?.findViewById<View>(viewId) != null) { if (i != 0) { recyclerView.scrollToPosition(i) uiController.loopMainThreadForAtLeast(500) } val targetView = viewHolder.itemView.findViewById<View>(viewId) action.perform(uiController, targetView) return } } } } }
我推测Kakao/Kaspresso可能在主线程循环处理上存在问题,但框架自带的防抖实现应该不需要手动处理主线程循环。求基于Kaspresso/Kakao实现需求的方案。
内容的提问来源于stack exchange,提问作者ceedee
相关产品推荐
相关产品推荐

