是否有滚动到非列表的常规方法查看屏幕上尚未显示的项目?
如果没有任何预防措施,Espresso将指示“层次结构中没有视图与id相匹配.....
我找到了这个答案......这是最好的方法吗?
onView( withId( R.id.button)).perform( scrollTo(), click());
答案 0 :(得分:20)
根据scrollTo
JavaDoc,要使用您指定的代码(onView( withId( R.id.button)).perform( scrollTo(), click());
),前提是:"必须是ScrollView的后代"和"必须将可见性设置为View.VISIBLE
"。如果是这种情况,那就可以了。
如果它位于AdapterView
,那么您应该使用onData
。在某些情况下,如果AdapterViewProtocol
表现不佳,则可能必须实施AdapterView
。
如果它既不是AdapterView
也不是ScrollView
的孩子,那么您必须实施自定义ViewAction
。
答案 1 :(得分:3)
如果你在android.support.v4.widget.NestedScrollView中有一个视图而不是scrollView scrollTo()不起作用。
为了工作,您需要创建一个实现ViewAction的类,就像ScrollToAction一样,但允许使用NestedScrollViews:
public Matcher<View> getConstraints() {
return allOf(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), isDescendantOfA(anyOf(
isAssignableFrom(ScrollView.class), isAssignableFrom(HorizontalScrollView.class), isAssignableFrom(NestedScrollView.class))));
}
额外提示并访问以下操作:
public static ViewAction betterScrollTo() {
return actionWithAssertions(new AllScrollViewsScrollToAction());
}
但是使用此滚动条不会触发布局管理器中的事件。
答案 2 :(得分:0)
对我有用的代码是:
ViewInteraction tabView = onView( allOf(childAtPosition(childAtPosition(withId(R.id.bottomControlTabView), 0), 1), isDisplayed()));
tabView.perform(click());
tabView.perform(click());
public static Matcher<View> childAtPosition(final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
答案 3 :(得分:0)
如果视图是 ScrollView、HorizontalScrollView 或 ListView 的后代,代码 <svg
attr.height="{{radius * 2}}"
attr.width="{{radius * 2}}"
>
<defs>
<lineargradient id="grad" x1="0" y1="0" x2="1" y2="1">
<stop offset="15%" stop-color="#FFF" stop-opacity="1"></stop>
<stop offset="85%" stop-color="#000" stop-opacity="1"></stop>
</lineargradient>
</defs>
<circle
class="gauge_base"
attr.cx="{{radius}}"
attr.cy="{{radius}}"
stroke="gray"
attr.r="{{innerRadius}}"
stroke-width="6px"
attr.transform="{{transform}}"
stroke-linecap="round"
fill="transparent"
attr.stroke-dasharray="{{dashArray}}"
/>
<circle
class="gauge_pourcentage"
attr.cx="{{radius}}"
attr.cy="{{radius}}"
attr.r="{{innerRadius}}"
stroke="url(#grad)"
attr.stroke-dasharray="{{dashArray}}"
stroke-width="12px"
attr.stroke-dashoffset="{{offset}}"
attr.transform="{{transform}}"
style="transition: stroke-dashoffset 0.3s"
stroke-linecap="round"
fill="transparent"
/>
</svg>
将起作用。
如果我们有 onView( withId( R.id.button)).perform( scrollTo(), click());
而不是 NestedScrollView
并且对于那些不想查看 ScrollView
类代码的人,我编写了示例。
作为 Bruno Oliveira said,我们可以这样做:
ScrollToAction
}
像这样使用它:
class ScrollToActionImproved : ViewAction {
override fun getConstraints(): Matcher<View> {
return allOf(
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
isDescendantOfA(
anyOf(
isAssignableFrom(ScrollView::class.java),
isAssignableFrom(HorizontalScrollView::class.java),
isAssignableFrom(NestedScrollView::class.java)
)
)
)
}
override fun getDescription(): String = "scroll to view"
override fun perform(uiController: UiController?, view: View?) {
if (isDisplayingAtLeast(90).matches(view)) {
//View is already displayed
return
}
val rect = Rect()
view!!.getDrawingRect(rect)
if (!view.requestRectangleOnScreen(rect, true)) {
//Scrolling to view was requested, but none of the parents scrolled.
}
uiController!!.loopMainThreadUntilIdle()
if (!isDisplayingAtLeast(90).matches(view)) {
throw PerformException.Builder()
.withActionDescription(this.description)
.withViewDescription(HumanReadables.describe(view))
.withCause(
RuntimeException(
"Scrolling to view was attempted, but the view is not displayed"
)
)
.build()
}
}
它应该可以工作。