我想滚动一个recyclerView并单击一个最初在屏幕上不可见的项目,但使用Espresso,但是滚动操作不起作用(在其他活动中的其他recyclerViews的其他测试中也是如此)。
我尝试了https://developer.android.com/training/testing/espresso/lists中指示的onData()方法
,但效果不佳。
这是我执行滚动并单击的方法:
fun scrollToPositionAndClick(resId: Int, position: Int) {
getActivityInstance()?.findViewById<RecyclerView>(resId)?.adapter?.let {
onView(withId(resId))
.perform(
scrollToPosition<RecyclerView.ViewHolder>(position),
actionOnItemAtPosition<RecyclerView.ViewHolder>(position, click())
)
}
}
此方法可在其他活动测试中使用,但由于某种原因,该方法不适用于此屏幕(碎片),并且出现此错误:
androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 290, 2197 and precision: 16, 16'
...
Caused by: androidx.test.espresso.PerformException: Error performing 'click (after 3 attempts)' on view 'unknown'.
答案 0 :(得分:0)
当ViewPager中有RecyclerView时,我没有滚动问题。我能够通过自己执行RecyclerViewAction.scrollToPosition来修复它。我没有使用recyclerView滚动条的API,而是使用LayoutManager的API,如果它是LinearLayoutManager,则使用了scrollToPositionWithOffset。
这是操作的代码。除了perform
方法
public final class CustomRecyclerViewActions {
private CustomRecyclerViewActions() { }
public static <VH extends RecyclerView.ViewHolder> ViewAction scrollToPosition(@IntRange(from = 0) final int position) {
return new ScrollToPositionViewAction(position);
}
private static final class ScrollToPositionViewAction implements ViewAction {
private final int position;
private ScrollToPositionViewAction(int position) {
this.position = position;
}
public Matcher<View> getConstraints() {
return Matchers.allOf(ViewMatchers.isAssignableFrom(RecyclerView.class), ViewMatchers.isDisplayed());
}
public String getDescription() {
int var1 = this.position;
return (new StringBuilder(44)).append("scroll RecyclerView to position: ").append(var1).toString();
}
public void perform(@NonNull UiController uiController, @NonNull View view) {
RecyclerView recyclerView = (RecyclerView)view;
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(this.position, 0);
} else {
layoutManager.scrollToPosition(this.position);
}
uiController.loopMainThreadUntilIdle();
}
}
}