Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Espresso, el desplazamiento no funciona cuando NestedScrollView o RecyclerView está en CoordinatorLayout

Parece que CoordinatorLayout rompe el comportamiento de las acciones de Espresso como scrollTo() o RecyclerViewActions.scrollToPosition() .

Problema con NestedScrollView

Para un diseño como este:

 <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> 

Si intento desplazarme a cualquier vista dentro del NestedScrollView usando ViewActions.scrollTo() el primer problema que encuentro es que consigo un PerformException . Esto se debe a que esta acción sólo admite ScrollView y NestedScrollView no lo extiende. Una solución para este problema se explica aquí , básicamente podemos copiar el código en scrollTo() y cambiar las restricciones para apoyar NestedScrollView . Esto parece funcionar si el NestedScrollView no está en un CoordinatorLayout pero tan pronto como lo pones dentro de un CoordinatorLayout la acción de desplazamiento falla.

Problema con RecyclerView

Para el mismo diseño, si reemplazo el NestedScrollView con un RecyclerView también hay problemas con el desplazamiento.

En este caso estoy usando RecyclerViewAction.scrollToPosition(position) . A diferencia de la NestedScrollView , aquí puedo ver algunos desplazamiento sucediendo. Sin embargo, parece que se desplaza a la posición equivocada. Por ejemplo, si me desplazo a la última posición, hace visible la segunda a la última pero no la última. Cuando muevo el RecyclerView fuera del CoordinatorLayout el desplazamiento funciona como debería.

Por el momento no podemos escribir ninguna prueba de Espresso para las pantallas que utilizan CoordinatorLayout debido a estos problemas. ¿Alguien que experimenta los mismos problemas o conoce una solución?

  • NestedScrolling con NestedScrollView, RecyclerView (Horizontal), dentro de un CoordinatorLayout
  • ConstraintLayout vs Coordinator?
  • CoordinatorLayout y AppBarLayout elevación
  • Cómo mostrar los elementos colapsados ​​en CoordinatorLayout mediante programación?
  • Posición de la vista de héroe calculada erróneamente durante la transición de elementos compartidos
  • CollapsingToolbarDescargar y ocultar la barra de herramientas mientras se desplaza
  • Diseño lib - CoordinatorLayout / CollapsingToolbarLayout con GridView / listView
  • 6 Solutions collect form web for “Espresso, el desplazamiento no funciona cuando NestedScrollView o RecyclerView está en CoordinatorLayout”

    Esto sucede porque el método scrollTo () de Espresso comprueba explícitamente la clase de diseño y sólo funciona para ScrollView y HorizontalScrollView. Internamente está usando View.requestRectangleOnScreen (…) así que esperaría que funcionara bien para muchos diseños.

    Mi solución para NestedScrollView era tomar ScrollToAction y modificar esa restricción. La acción modificada funcionó correctamente para NestedScrollView con ese cambio.

    Método cambiado en la clase ScrollToAction:

     public Matcher<View> getConstraints() { return allOf(withEffectiveVisibility(Visibility.VISIBLE), isDescendantOfA(anyOf( isAssignableFrom(ScrollView.class), isAssignableFrom(HorizontalScrollView.class), isAssignableFrom(NestedScrollView.class)))); } 

    Método de conveniencia:

     public static ViewAction betterScrollTo() { return ViewActions.actionWithAssertions(new NestedScrollToAction()); } 

    Tenía este problema con CoordinatorLayout-> ViewPager-> NestedScrollView un trabajo fácil alrededor de mí para conseguir el mismo scrollTo () el comportamiento era apenas deslizar para arriba en la pantalla:

     onView(withId(android.R.id.content)).perform(ViewActions.swipeUp()); 

    Este problema ha sido reportado (quizás por el OP?), Vea el número 203684

    Uno de los comentarios a ese problema sugiere un trabajo alrededor del problema cuando el NestedScrollView está dentro de un CoordinatorLayout:

    @string/appbar_scrolling_view_behavior quitar el comportamiento de disposición @string/appbar_scrolling_view_behavior o cualquier vista principal que este ScrollingView esté incluido en

    Aquí está una implementación de ese work-around:

      activity.runOnUiThread(new Runnable() { @Override public void run() { // remove CoordinatorLayout.LayoutParams from NestedScrollView NestedScrollView nestedScrollView = (NestedScrollView)activity.findViewById(scrollViewId); CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)nestedScrollView.getLayoutParams(); params.setBehavior(null); nestedScrollView.requestLayout(); } }); 

    Pude obtener mis pruebas de trabajo por:

    1. Realización de una acción scrollTo () personalizada (como se hace referencia en el OP y Turnsole)
    2. Eliminar los parámetros de diseño de NestedScrollView como se muestra aquí

    He hecho una clase NestedScrollViewScrollToAction.

    Creo que es mejor lugar para hacer actividades específicas cosas allí en su lugar.

    La única cosa digno de mencionar es que el código busca el nestedScrollView del padre y quita su comportamiento de CoordinatorLayout.

    https://gist.github.com/miszmaniac/12f720b7e898ece55d2464fe645e1f36

    La solución del Sr. Mido puede funcionar en algunas situaciones, pero no siempre. Si tiene alguna vista en la parte inferior de la pantalla, el desplazamiento de su RecyclerView no sucederá porque el clic comenzará fuera de la RecyclerView.

    Una manera de solucionar este problema es escribir un SwipeAction personalizado. Me gusta esto:

    1 – Cree la acción 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()); } } 

    2 – Crear el método para devolver el 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); } 

    3 – A continuación, utilícelo para desplazarse por la pantalla:

     onView(withId(android.R.id.content)).perform(swipeFromCenterToTop()); 

    ¡Y eso es! De esta manera usted puede controlar cómo el rollo va a suceder en su pantalla.

    El scrollTo(R.id.button) de Barista scrollTo(R.id.button) funciona en todo tipo de vistas desplazables, también en NestedScrollView .

    Es útil para solucionar este tipo de problemas con Espresso. Lo desarrollamos y utilizamos sólo para escribir exámenes Espresso de una manera rápida y confiable. Y aquí hay un enlace: https://github.com/SchibstedSpain/Barista

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.