scrolling recyclerview not inside ejemplo android android-recyclerview nestedscrollview

android - not - scroll recyclerview



¿Cómo poner RecyclerView dentro de NestedScrollView? (3)

Con la creación de NestedScrollView , puede colocar la vista de desplazamiento dentro de otra vista de desplazamiento siempre que implementen NestedScrollingChild y NestedScrollingParent correctamente.

(Este no es un mal patrón de diseño "Ian Lake (de Google) realmente recomienda poner un RecyclerView dentro de una vista de desplazamiento anidada aquí: plus.google.com/u/0/+AndroidDevelopers/posts/9kZ3SsXdT2T")

Quiero poner RecyclerView dentro de NestedScrollView y afortunadamente RecyclerView implementa NestedScrollingChild para que puedas ponerlo dentro de NestedScrollView .

public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild

He leído estas publicaciones:

¿Cómo usar RecyclerView dentro de NestedScrollView?

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

Pero el problema con la solución más votada es que llama a todos los elementos de RecyclerView por ejemplo, si es un RecyclerView interminable y cuando el usuario llega al final de la lista, desea hacer una solicitud de red, entonces con esa solución, el RecyclerView llama servidor repetidamente porque alcanza automáticamente el último elemento de RecyclerView .

De todos modos, cómo configurar el parámetro para que pueda poner RecyclerView dentro de NestedScrollView . (En realidad quiero poner un grupo de vista como framelayout o relativelayout como un solo childe de nestedscrollview y luego quiero poner reciccviewview dentro de framelayout o relativelayout)

Cuando pongo RecyclerView dentro de NestedScrollView no hay nada que mostrar.

Para crear un proyecto de muestra, puede usar cheesesquare y cambiar CheeseDetailActivity para tener un RecyclerView.

Aunque la respuesta de BNK no es correcta, BNK ha intentado mucho. Entonces le otorgo la recompensa. Todavía estoy buscando una buena solución ...


Aquí hay una solución para llamar al servidor solo cuando realmente necesite cargar más datos. De esta manera, puede poner su RecyclerView sin fin y muchas otras vistas dentro de NestedScrollView. Para mí está funcionando bien.

1. Cree la clase EndlessParentScrollListener para manejar eventos de desplazamiento desde NestedSrollView.

public abstract class EndlessParentScrollListener implements NestedScrollView.OnScrollChangeListener { // The current offset index of data you have loaded private int currentPage = 0; // The total number of items in the dataset after the last load private int previousTotalItemCount = 0; // True if we are still waiting for the last set of data to load. private boolean loading = true; // Sets the starting page index private int startingPageIndex = 0; // The minimum amount of pixels to have below your current scroll position // before loading more. private int visibleThresholdDistance = 300; RecyclerView.LayoutManager mLayoutManager; public EndlessParentScrollListener(RecyclerView.LayoutManager layoutManager) { this.mLayoutManager = layoutManager; } @Override public void onScrollChange(NestedScrollView scrollView, int x, int y, int oldx, int oldy) { // We take the last son in the scrollview View view = scrollView.getChildAt(scrollView.getChildCount() - 1); int distanceToEnd = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY())); int totalItemCount = mLayoutManager.getItemCount(); // If the total item count is zero and the previous isn''t, assume the // list is invalidated and should be reset back to initial state if (totalItemCount < previousTotalItemCount) { this.currentPage = this.startingPageIndex; this.previousTotalItemCount = totalItemCount; if (totalItemCount == 0) { this.loading = true; } } // If it’s still loading, we check to see if the dataset count has // changed, if so we conclude it has finished loading and update the current page // number and total item count. if (loading && (totalItemCount > previousTotalItemCount)) { loading = false; previousTotalItemCount = totalItemCount; } // If it isn’t currently loading, we check to see if we have breached // the visibleThreshold and need to reload more data. // If we do need to reload some more data, we execute onLoadMore to fetch the data. // threshold should reflect how many total columns there are too if (!loading && distanceToEnd <= visibleThresholdDistance) { currentPage++; onLoadMore(currentPage, totalItemCount); loading = true; } } // Defines the process for actually loading more data based on page public abstract void onLoadMore(int page, int totalItemsCount); }

2. Establecer oyente

private void initRecycler() { //TODO init recycler adapter here recycler.setNestedScrollingEnabled(false); LinearLayoutManager _layoutManager = new LinearLayoutManager(this); recycler.setLayoutManager(_layoutManager); NestedScrollView scrollView = (NestedScrollView) findViewById(R.id.scrollView); scrollView.setOnScrollChangeListener(new EndlessParentScrollListener(_layoutManager) { @Override public void onLoadMore(int page, int totalItemsCount) { if (loadedItemCount < serverItemsCount) customLoadMoreDataFromApi(); } }); customLoadMoreDataFromApi(); }

Xml corto si alguien lo encuentra útil:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/background_light" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout> ... </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:scrollbars="vertical" android:scrollbarAlwaysDrawVerticalTrack="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:scrollbarAlwaysDrawVerticalTrack="false" android:scrollbars="vertical"> <!-- some views goes here--> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerFeed" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <!-- and possibly here--> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>


Así que poner RecyclerView dentro de NestedScrollView directamente desafortunadamente no mostrará nada. Sin embargo, hay una manera de poner la vista de reciclador dentro de NestedScrollView indirectamente: solo use un frameLayout como el tercero para mantener su vista de reciclador.

Este es el framelayout que contiene la vista de reciclador anidada en su clase de actividad :

<FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".ExampleFragment" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" > </android.support.v4.widget.NestedScrollView> </FrameLayout>

Coloque su fragmento en el framelayout (el código se encuentra dentro de la clase de actividad ):

ExampleFragment exampleFragment = new ExampleFragment(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.container, exampleFragment); ft.commit();

En su fragmento de ejemplo , puede poner su vista de reciclador.

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/post_container" android:background="#E0E0E0"> <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </RelativeLayout>

Este es el código de fragmento :

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); llLayout = (RelativeLayout) inflater.inflate(R.layout.example_fragment_layout, container, false); mRecyclerView = (RecyclerView) llLayout.findViewById(R.id.my_recycler_view);

El siguiente es el diseño XML CheeseSquare que debe tener:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="@dimen/detail_backdrop_height" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginStart="48dp" app:expandedTitleMarginEnd="64dp"> <ImageView android:id="@+id/backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:fitsSystemWindows="true" app:layout_collapseMode="parallax" /> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_collapseMode="pin" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".ExampleFragment" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" > </android.support.v4.widget.NestedScrollView> </FrameLayout> <android.support.design.widget.FloatingActionButton android:layout_height="wrap_content" android:layout_width="wrap_content" app:layout_anchor="@id/appbar" app:layout_anchorGravity="bottom|right|end" android:src="@drawable/ic_discuss" android:layout_margin="@dimen/fab_margin" android:clickable="true"/> </android.support.design.widget.CoordinatorLayout>


La siguiente es mi nueva respuesta actualizada:

<android.support.v4.widget.NestedScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:id="@+id/cardview1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/card_margin"> <LinearLayout style="@style/Widget.CardContent" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Info CardView1" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/cheese_ipsum" /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:id="@+id/cardview2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/cardview1" android:layout_margin="@dimen/card_margin"> <LinearLayout style="@style/Widget.CardContent" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Info CardView2" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/cheese_ipsum" /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/cardview2" android:clipToPadding="false" android:paddingTop="0dp"/> </RelativeLayout> </android.support.v4.widget.NestedScrollView>

En actividad:

RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(true); // true: with header RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); final MyLinearLayoutManager layoutManager = new MyLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false, getScreenHeight(this)); // final CustomLinearLayoutManager layoutManager = new CustomLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(recyclerViewAdapter); // recyclerView.setNestedScrollingEnabled(false); // Disables scrolling for RecyclerView, however, CustomLinearLayoutManager used instead of MyLinearLayoutManager

También he actualizado al proyecto de muestra de My GitHub

Captura de pantalla: