android / architecture-components-samples

Samples for Android Architecture Components.
https://d.android.com/arch
Apache License 2.0
23.39k stars 8.29k forks source link

PagingLibrary and NestedScrollView problem. #215

Closed Smatek94 closed 4 years ago

Smatek94 commented 6 years ago

When developing my application I was using PagingLibrary. It was working perfect. However at some point I decided to wrap my RecyclerView into NestedScrollView. Problem is that when I have done it, function that was responsible for loading data (loadIinitial from KeyedDataSource class) was being called till it loaded all data instead of only one page. Without NestedScrollView it is loading pages well. I tried using setNestedScrollingEnabled(false) or with true but it didn't helped.

Fishfield commented 6 years ago

I have exactly the same problem. I reported it already to google, see issue. For me this not an edge case, e.g. if you are using CoordinatorLayout which needs nested scrolling at some point. @Smatek94 did you find a solution for the problem already?

Smatek94 commented 6 years ago

sadly I didn't find soultion when I was delevoping this case.

danaimset commented 6 years ago

Hi there! Take a look at the gist for the solution: "pass down to RecyclerView AT_MOST its own size to work around": issue SmartNestedScrollView

But in case you have 2 RecyclerViews in your layout you may want to scroll entire page (containing 2 recycler views). In that case CoordinatorLayout can help to archive this check out the following gist: activity_nested_recyclers Does anybody know about any other solution?

And don't forget to add android:fillViewport="true" to scrollable container

edwardstock commented 6 years ago

@danaimset it works like magic! But, for those who will use this trick, don't forget to set list.setNestedScrollingEnabled(true). Without this line, recycler will not be able to scroll. Only collapsinglayout is collapsing.

aungtuntun commented 5 years ago

Thanks @edwardstock , recyclerview.setNestedScrollingEnabled(true) is worked for me. You save my time.

n-abdelmaksoud commented 5 years ago

Hi there, I have the same problem: NestedScrollView wrapping a some TextViews and RecyclerView (PagingLibrary). I tried this SmartNestedScrollView and the loading works fine but the TextViews are still pinned at the top of the RecyclerView. I want them to scroll too. Do i implement something wrong or that is the normal behavior?

abhishekhugetech commented 5 years ago

@nerrydanna Did you find any solution for the problem. I am having the same problem every view in the layout sits at the same position and only a small portion of recycler view which is visible on the screen is getting scrolled.

If you have found any solution for this issue please help me.

n-abdelmaksoud commented 5 years ago

@abhishekhugetech I couldn’t find a solution for it but i’ve used another way. I’ve used CoordinatorLayout with CollapsingToolBar containing the views you want to scroll and set collapsing mode to “none” to get scrolling behavior

ruthwikkk commented 4 years ago

@abhishekhugetech @nerrydanna I am facing the same issue. If you found any solution, that will be helpful

thomas819 commented 4 years ago

my solution is NestedScrollView -> CoordinatorLayout it's work!!

danaimset commented 4 years ago

If you're using collapsing toolbar then if you're scrolling with high velocity you'll probably notice the paged list scrolled under collapsing toolbar. Will be great to have a solution for that issue. I don't have one for now. Do you?

iAmMONK commented 4 years ago

@danaimset nice workaround but then you can't setup scrollbar :( + sometimes on fast scroll the Appbar recyclerview gets stuck How careless can they be ? This is open since 2 years and all we got : "It's not a problem of paging library so fuck off." Here is another issue that is still open, so click on stare. Maybe they will hear us. Anyway, took a look at the issue tracker, there is no milestone set and they have tons of bugs. Looks like the library is abandoned...

danaimset commented 4 years ago

@iAmMONK there are still a lot of issues.... Now I'm looking at the following approach: https://github.com/airbnb/epoxy/blob/master/epoxy-pagingsample/src/main/java/com/airbnb/epoxy/pagingsample/PagingSampleActivity.kt

I've just finished another sample based on PagedListEpoxyController. It looks very promising There are multiple ways how to mix items from DataSource and any other pieces of UI, i.e. headers. If anybody interested, please, let me know I'll share it. But AirBnb's should be enough. It looks hard and complicated. But actually API is well enough to make complicated recyclers in a small amount of time.

iAmMONK commented 4 years ago

@danaimset Oh wow, If you could share a sample that would be great !

iAmMONK commented 4 years ago

I have also created another issue for RV already. If the Paging Team says it's not their problem, then maybe RV team can fix it ?

https://issuetracker.google.com/issues/145110710

Note: If you star the issues, they might move faster ;)

danaimset commented 4 years ago

@danaimset Oh wow, If you could share a sample that would be great !

Unfortunately I didn't have a chance to prepare my own sample but I'm pleased to share with you a good article how to setup epoxy paged list controller: https://medium.com/@vkalmath.dev/paging-with-epoxy-a4b5a4f860b5

You can override addModels if you want to add any blocks you need. For ex.:

override fun addModels(models: List<EpoxyModel<*>>) {
        val staticModels = ArrayList<EpoxyModel<*>>().apply {

            // Info
            profile?.let {
                add(createProfileHeader(it))
            }
        }
        super.addModels(staticModels + models)
}

private fun createProfileHeader(profile: Profile): EpoxyModel<*> {
        return HeaderProfileBindingModel_()
                .id("profile")
                .profile(profile)
}
ianhanniballake commented 4 years ago

This issue isn't related to these samples. Feel free to read through the issue on the issue tracker.

doctor-henry commented 4 years ago

Based on Android documentation:

Never add a RecyclerView or ListView to a scroll view. Doing so results in poor user interface performance and a poor user experience.

The best new way is to use MergeAdapter. It added to Recyclerview v1.2.0alpha. So add this dependency:

implementation "androidx.recyclerview:recyclerview:1.2.0-alpha03"

If you want to put two Adapters in one recyclerView, follow this Guide:

then make an instance of MakeAdapter and pass your adapters on it then set it as RecyclerViewAdapter:

MergeAdapter ma = new (firstAdapter, secondAdapter);
myRecyclerView.setAdapter(ma);

If you have a layout and Pagedlist, follow this guide:

Then Make and Simple ViewHolder and put the first layout on it. Then make MergeAdapter then add your layout's adapter and then PagedList's adapter, then add adapter of PagedList:

MergeAdapter ma = new MergeAdapter();
ma.addAdaper(simpleAdapter);
ma.addAdapter(pagedListAdapter);

then set this mergeAdapter to recyclerView's adapter;

myRecyclerView.setAdapter(ma);
allefsousa commented 4 years ago

Same problem here, someone solution to use recyclerview +NestedScrollView + Pagin Library ?

doctor-henry commented 4 years ago

Same problem here, someone solution to use recyclerview +NestedScrollView + Pagin Library ?

please don't do it. It reduces performance a lot (maybe later)

danaimset commented 4 years ago

@allefsousa Why do you still need NestedScrollView if you're using single RecyclerView with MergeAdapter? I guess that you don't need outer NestedScrollView If you're using MergeAdapter.

allefsousa commented 4 years ago

@allefsousa Por que você ainda precisa do NestedScrollView se está usando o único RecyclerView com MergeAdapter? Eu acho que você não precisa de NestedScrollView externo Se estiver usando o MergeAdapter.

Today I have a structure like this:

<NestedScrollView> 
<ViewPager>
<\ViewPager>
<RecyclerView>
<\RecyclerView>
<RecyclerView>
<PagingLibrary>
<\RecyclerView>
<\NestedScrollView>

I will evaluate using the merge adapter.

danaimset commented 4 years ago

@allefsousa So from the answer https://github.com/android/architecture-components-samples/issues/215#issuecomment-627551019 the proposal is to reorganize layout in the following manner:

You will have single RecyclerView with MergeAdapter

MergeAdapter should contain the following adapters:

  1. Adapter with single item i.e. ViewPager
  2. Adapter displaying items from the RecyclerView laid out right below ViewPager
  3. Paging adapter with items from DataSource.Factory (i.e. PagedListAdapter)

Seems that it should work

allefsousa commented 4 years ago

@danaimset Problem solved using merge adapter and only a recyclerview. However, I did not use the paging library because there was the same error reported by @Smatek94. I used an approach related to observing the recyclerview scroll and retrieving the data. Thank you

chihuy105 commented 4 years ago

Okey I found a solution for this, different from all of the above, it's a little bit odd but it's worked perfectly. I put all the views that need to scroll in the NestedScrollView into a CollapsingToolbarLayout. After that i create a view pager and wrap it with the NestedScrollView. I create a Fragment and put the Recyclerview inside the Fragment. Here is the full example in stackoverflow: https://stackoverflow.com/a/62018844/7548514

hellosagar commented 4 years ago

@danaimset it works like magic! But, for those who will use this trick, don't forget to set list.setNestedScrollingEnabled(true). Without this line, recycler will not be able to scroll. Only collapsinglayout is collapsing.

No working for me as it is showing nothing on display please help thanks

hellosagar commented 4 years ago

On replacing NestedScrollView with SmartNestedScrollView nothing is showing please help thanks

edwardstock commented 4 years ago

On replacing NestedScrollView with SmartNestedScrollView nothing is showing please help thanks

What exactly does not working?

hellosagar commented 4 years ago

@edwardstock let me show you my code

hellosagar commented 4 years ago

@edwardstock this is my XML `<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="true" android:focusableInTouchMode="true" android:background="#F6F6F6" tools:context=".activity.HealthCentresActivity">

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar_health_centres"
    android:layout_width="match_parent"
    android:elevation="4dp"
    app:titleTextColor="@color/drawer_item_color"
    android:background="@android:color/white"
    android:layout_height="?attr/actionBarSize"
    app:layout_constraintEnd_toEndOf="parent"
    android:theme="@style/ThemeOverlay.AppCompat.Light"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<ProgressBar
    android:id="@+id/progress_health_centres"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:indeterminate="true"
    android:indeterminateTint="@color/blue"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="@+id/nestedScrollView2"
    app:layout_constraintTop_toTopOf="@+id/nestedScrollView2" />

<com.kai.infomed.SmartNestedScrollView
    android:id="@+id/nestedScrollView2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/toolbar_health_centres">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_health_centre_consultant"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="8dp"
            android:background="@drawable/rounded_search_background"
            android:elevation="2dp"
            android:visibility="invisible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <ImageView
                android:layout_width="30dp"
                android:layout_height="34dp"
                android:layout_marginEnd="16dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/search_blue"
                tools:ignore="ContentDescription" />

            <EditText
                android:id="@+id/etHealthcenter"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_marginStart="16dp"
                android:background="@null"
                android:ems="10"
                android:imeOptions="actionDone"
                android:hint="@string/search_health_centre"
                android:inputType="textPersonName"
                android:padding="8dp"
                android:textColor="@color/black_medium"
                android:textColorHint="@color/search_hint"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:ignore="Autofill" />
        </androidx.constraintlayout.widget.ConstraintLayout>

        <TextView
            android:id="@+id/textView25"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="@string/category"
            android:visibility="invisible"
            android:textColor="@color/sub_heading"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="@+id/cl_health_centre_consultant"
            app:layout_constraintTop_toBottomOf="@+id/cl_health_centre_consultant" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_consultant_health_center"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:overScrollMode="never"
            android:visibility="invisible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView25" />

        <TextView
            android:id="@+id/textView26"
            android:visibility="invisible"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="@string/centres"
            android:textColor="@color/sub_heading"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="@+id/textView25"
            app:layout_constraintTop_toBottomOf="@+id/rv_consultant_health_center" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_heath_centres"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView26" />

        <TextView
            android:id="@+id/textView32"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            android:text="@string/no_result"
            android:visibility="gone"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/rv_heath_centres"
            tools:visibility="visible" />

        <ProgressBar
            android:id="@+id/progressBar_centres_health_centres"
            style="?android:attr/progressBarStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            android:indeterminate="true"
            android:visibility="gone"
            android:indeterminateTint="@color/blue"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/rv_heath_centres" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</com.kai.infomed.SmartNestedScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>`

hellosagar commented 4 years ago

@edwardstock I just replace NestedScrollView with SmartNestedScrollView and it is not working and other than that I need to do anything else? If I replace SmartNestedScrollView with NestedScrollView everything is showing but data is loaded at once and when I replace NestedScrollView with SmartNestedScrollView nothing is showing Thanks for replying sir

edwardstock commented 4 years ago

@edwardstock I just replace NestedScrollView with SmartNestedScrollView and it is not working and other than that I need to do anything else? If I replace SmartNestedScrollView with NestedScrollView everything is showing but data is loaded at once and when I replace NestedScrollView with SmartNestedScrollView nothing is showing Thanks for replying sir

Try to add to the SmartNestedScrollView: android:fillViewport="true"

danaimset commented 4 years ago

@sagarkhurana00786 In case it's not working make sure you have only one recycler view under SmartNestedScrollView. It wraps only single recycler view (first available). If you need multiple RecyclerViews it's better using MergeAdapter https://github.com/android/architecture-components-samples/issues/215#issuecomment-627551019 You can also try 3d party solutions like Epoxy

hellosagar commented 4 years ago

@danaimset oh! now I know why it is not working and it is working for only one recyclerview and even second one is also now showing all data and how can I use mergeadapter because as I need two reyclerview with one of horizontal orientation and one with vertical and ow can I fulfill this requirement so now what I haven't tried is Expoxy and nestedrecyclerview approach I'm going with one of the approaches as merge adapter and smartnestedscrollvierw is not working for me Is I'm wrong or Right and if you have another solution tell me thanks I'm sharing my layout through which u get the idea what I need lay Thanks for replying and giving your time

danaimset commented 4 years ago

Well, cause you have recycler views with different layout managers using MergeAdapter may be a problem. So what I'd recommend: Modify the code of SmartNestedScrollView to find recycler view which should be limited with the height of the viewport (find it by ID or get the last one in hierarchy: it should work in your case).

If you want to use Epoxy do the following with your top recycler view: https://github.com/airbnb/epoxy/wiki/Carousel And of course for main paged list: https://github.com/airbnb/epoxy/wiki/Paging-Support

hellosagar commented 4 years ago

Thanks for replying but I didn't your approach of Modifying code in SmartNestedScrollView what I need to change in that like u have two methods in that class are you talking about findNestedRecyclerView this method? and if yes what I need to modify in that see when I use smartnestedrecyclerview I get this output and not able to scroll more at the bottom in 2nd recycler view it stuck in between item WhatsApp Image 2020-06-15 at 12 31 01 PM Thanks

hellosagar commented 4 years ago

@danaimset Thanks for replying but I didn't your approach of Modifying code in SmartNestedScrollView what I need to change in that like u have two methods in that class are you talking about findNestedRecyclerView this method? and if yes what I need to modify in that see when I use smartnestedrecyclerview I get this output and not able to scroll more at the bottom in 2nd recycler view it stuck in between item WhatsApp Image 2020-06-15 at 12 31 01 PM Thanks

smartsatu commented 4 years ago

If you want to have the entire page scroll, check this approach: https://gist.github.com/danaimset/6c5c21e918c99eb90c2b9f1e862f2d22 Everything above "Dentist Centres" can be scrolled by CollapsingToolbar. "Dentist Centeres" itself: recycler view included in SmartNestedScrollView.

hellosagar commented 4 years ago

@smartsatu I think that's now a good solution What's your views on this

Paget96 commented 4 months ago

Still no solutions?