NestedScrolling con NestedScrollView, RecyclerView (Horizontal), dentro de un CoordinatorLayout

Tengo un diseño de la interfaz de usuario con CollapsingToolbarLayout, como el siguiente.

<android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="@dimen/detail_backdrop_height" android:fitsSystemWindows="true" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginEnd="64dp" app:expandedTitleMarginStart="48dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:id="@+id/backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:scaleType="centerCrop" app:layout_collapseMode="parallax" /> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:fillViewport="true" android:theme="@style/ThemeOverlay.AppCompat.Light" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingTop="24dp"> <!-- Hiding unrelated code --> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/card_margin" android:padding="16dp"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_movie_suggestion" android:layout_width="match_parent" android:layout_height="170dp" android:fillViewport="true" android:nestedScrollingEnabled="false" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout> </android.support.v4.widget.NestedScrollView> 

Mi problema es que el desplazamiento está bien SOLAMENTE cuando toco y desplazo el área FUERA del RecyclerView. Si trato de desplazarse verticalmente dentro del RecyclerView, el desplazamiento está "atrapado" y SÓLO el NestedScrollView se desplaza, el CollaspingToolbarLayout IS NOT collasping.

Es necesario deshabilitar el desplazamiento anidado mediante programación. Parece que no funciona correctamente si se realiza en xml.

 recyclerView.setNestedScrollingEnabled(false); 

Este es el problema más común al usar recyclerview dentro de nestedscrollview.

He arreglado esto mediante la adición de las siguientes líneas en xml.

 <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view_comments" android:layout_width="match_parent" android:layout_height="wrap_content" android:nestedScrollingEnabled="false" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

Oye, si estás interesado, he creado un LayoutManager que debería resolver tu problema.

 public class ExpansiveLayoutManager extends LinearLayoutManager { private int[] mMeasuredDimension = new int[2]; public ExpansiveLayoutManager(Context context) { super(context); } public ExpansiveLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } public ExpansiveLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public boolean canScrollVertically() { return false; } @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0; int height = 0; for (int i = 0; i < getItemCount(); i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { width = width + mMeasuredDimension[0]; if (i == 0) { height = mMeasuredDimension[1]; } } else { height = height + mMeasuredDimension[1]; if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { View view = recycler.getViewForPosition(position); if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } } 

https://github.com/emanuelet/LayoutManagers/blob/master/ExpansiveLayoutManager.java

No es necesario que ponga su recyclerView dentro de NestedScrollView.

 <android.support.v7.widget.RecyclerView android:id="@+id/recycler_movie_suggestion" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:layout_height="170dp" /> 

No es necesario utilizar NestedScrollView. Sólo deje LinearLayout allí.

  • No se puede llamar a void android.view.View.setTranslationZ (float) en un objeto null
  • Force RecyclerView para volver a dibujar Android
  • Cómo persistir grandes datos RecyclerView en los cambios de orientación?
  • Cómo mostrar la fecha entre conversación en recyclerview o en listview
  • CoordinatorLayout con RecyclerView
  • Recyclerview se bloquea al eliminar el último elemento. NullPointerException: android.view.ViewGroup $ LayoutParams android.view.View.getLayoutParams ()
  • Desactivación del comportamiento de desplazamiento de Android CoordinatorLayout
  • RecyclerView sin barra de desplazamiento cuando se desactiva el desplazamiento excesivo
  • Vista de Google Maps dentro de un RecyclerView
  • Definición de onclickListener de RecyclerView en una actividad
  • Recyclerview con múltiples temporizadores de cuenta regresiva causa parpadeo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.