scrolling recyclerview not inside fillviewport ejemplo android android-recyclerview coordinator-layout nestedscrollview

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



scroll recyclerview (5)

Tengo un diseño de 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 SÓLO cuando toco y desplazo el área FUERA de RecyclerView. Si trato de desplazarme verticalmente dentro de RecyclerView, el desplazamiento está "atrapado" y SÓLO se está desplazando el NestedScrollView, CollaspingToolbarLayout NO está collapse.


Necesita desactivar el desplazamiento anidado programáticamente. No parece funcionar correctamente si se hace en xml.

recyclerView.setNestedScrollingEnabled(false);


Hola, si estás interesado creé 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 necesita colocar 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" />


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

Lo he arreglado agregando 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" />


No es necesario que use NestedScrollView. Solo deja LinearLayout allí.