iva*_*acf 35 android android-espresso android-recyclerview coordinator-layout android-nestedscrollview
它似乎CoordinatorLayout打破了Espresso行为的行为,如scrollTo()或RecyclerViewActions.scrollToPosition().
对于像这样的布局:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
...
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
...
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
如果我尝试滚动到NestedScrollView使用ViewActions.scrollTo()第一个问题内部的任何视图我发现是我得到了PerformException.这是因为这个动作只支持ScrollView并NestedScrollView不会扩展它.此处解释了此问题的解决方法,基本上我们可以复制代码scrollTo()并更改约束以支持NestedScrollView.这似乎有效,如果NestedScrollView它不在一个CoordinatorLayout但只要你把它放在CoordinatorLayout滚动动作失败.
对于相同的布局,如果我替换了NestedScrollViewa RecyclerView,则滚动也存在问题.
在这种情况下,我正在使用RecyclerViewAction.scrollToPosition(position).不像NestedScrollView,在这里我可以看到一些滚动发生.但是,它看起来像滚动到错误的位置.例如,如果我滚动到最后一个位置,它会显示倒数第二个但不是最后一个.当我移动RecyclerView了的CoordinatorLayout滚动运作,因为它应该.
目前我们无法CoordinatorLayout为因此问题而使用的屏幕编写任何Espresso测试.任何遇到相同问题或知道解决方法的人?
Tur*_*ole 25
发生这种情况是因为Espresso scrollTo()方法显式检查布局类,仅适用于ScrollView和HorizontalScrollView.在内部它使用View.requestRectangleOnScreen(...)所以我希望它实际上适用于许多布局.
我对NestedScrollView的解决方法是采用ScrollToAction并修改该约束.修改后的操作适用于NestedScrollView并进行了更改.
ScrollToAction类中的已更改方法:
public Matcher<View> getConstraints() {
return allOf(withEffectiveVisibility(Visibility.VISIBLE), isDescendantOfA(anyOf(
isAssignableFrom(ScrollView.class), isAssignableFrom(HorizontalScrollView.class), isAssignableFrom(NestedScrollView.class))));
}
Run Code Online (Sandbox Code Playgroud)
便利方法:
public static ViewAction betterScrollTo() {
return ViewActions.actionWithAssertions(new NestedScrollToAction());
}
Run Code Online (Sandbox Code Playgroud)
tas*_*iac 14
以下是我和@miszmaniac在Kotlin做过同样的事情.随着在Kotlin的代表团,它更清洁,更容易,因为我不必覆盖我不需要的方法.
class ScrollToAction(
private val original: android.support.test.espresso.action.ScrollToAction = android.support.test.espresso.action.ScrollToAction()
) : ViewAction by original {
override fun getConstraints(): Matcher<View> = anyOf(
allOf(
withEffectiveVisibility(Visibility.VISIBLE),
isDescendantOfA(isAssignableFrom(NestedScrollView::class.java))),
original.constraints
)
}
Run Code Online (Sandbox Code Playgroud)
MR *_*ido 11
我有这个问题与CoordinatorLayout-> ViewPager-> NestedScrollView一个简单的工作从我得到相同的scrollTo()行为只是在屏幕上向上滑动:
onView(withId(android.R.id.content)).perform(ViewActions.swipeUp());
Run Code Online (Sandbox Code Playgroud)
米多先生的解决方案在某些情况下可能会奏效,但并非总是如此。如果屏幕底部有一些视图,则 RecyclerView 的滚动不会发生,因为单击将在 RecyclerView 之外开始。
解决此问题的一种方法是编写自定义 SwipeAction。像这样:
1 - 创建 CenterSwipeAction
public class CenterSwipeAction implements ViewAction {
private final Swiper swiper;
private final CoordinatesProvider startCoordProvide;
private final CoordinatesProvider endCoordProvide;
private final PrecisionDescriber precDesc;
public CenterSwipeAction(Swiper swiper, CoordinatesProvider startCoordProvide,
CoordinatesProvider endCoordProvide, PrecisionDescriber precDesc) {
this.swiper = swiper;
this.startCoordProvide = startCoordProvide;
this.endCoordProvide = endCoordProvide;
this.precDesc = precDesc;
}
@Override public Matcher<View> getConstraints() {
return withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE);
}
@Override public String getDescription() {
return "swipe from middle of screen";
}
@Override
public void perform(UiController uiController, View view) {
float[] startCoord = startCoordProvide.calculateCoordinates(view);
float[] finalCoord = endCoordProvide.calculateCoordinates(view);
float[] precision = precDesc.describePrecision();
// you could try this for several times until Swiper.Status is achieved or try count is reached
try {
swiper.sendSwipe(uiController, startCoord, finalCoord, precision);
} catch (RuntimeException re) {
throw new PerformException.Builder()
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(view))
.withCause(re)
.build();
}
// ensures that the swipe has been run.
uiController.loopMainThreadForAtLeast(ViewConfiguration.getPressedStateDuration());
}
}
Run Code Online (Sandbox Code Playgroud)
2 - 创建返回 ViewAction 的方法
private static ViewAction swipeFromCenterToTop() {
return new CenterSwipeAction(Swipe.FAST,
GeneralLocation.CENTER,
view -> {
float[] coordinates = GeneralLocation.CENTER.calculateCoordinates(view);
coordinates[1] = 0;
return coordinates;
},
Press.FINGER);
}
Run Code Online (Sandbox Code Playgroud)
3 - 然后用它来滚动屏幕:
onView(withId(android.R.id.content)).perform(swipeFromCenterToTop());
Run Code Online (Sandbox Code Playgroud)
就是这样!通过这种方式,您可以控制滚动在屏幕中的发生方式。
Barista 的scrollTo(R.id.button)作品涉及各种可滚动视图,也涉及NestedScrollView.
使用 Espresso 解决此类问题很有用。我们开发和使用它只是为了以快速可靠的方式编写 Espresso 测试。这是一个链接: https: //github.com/SchibstedSpain/Barista
| 归档时间: |
|
| 查看次数: |
10609 次 |
| 最近记录: |