Infeasible
Status Update
Comments
yb...@google.com <yb...@google.com> #2
when you put recyclerview inside an infinite scrolling parent, it will layout all of its children because the parent provides infinite dimensions.
I recommend changing NSV implementation to pass down to RecyclerView AT_MOST its own size to work around this.
Unfortunately, NSV cannot reliably do this because it does not know where RV is added nor if it wants to not layout its chidlren.
I recommend changing NSV implementation to pass down to RecyclerView AT_MOST its own size to work around this.
Unfortunately, NSV cannot reliably do this because it does not know where RV is added nor if it wants to not layout its chidlren.
[Deleted User] <[Deleted User]> #3
Ok thanks for the quick response.
So that means everyone who uses the paging library and puts a RV into a NSV has to come up with its own implementation of the NSV? From my point of view this a quite common use case.
Do you have any code example or suggestion how this can exactly be resolved using AT_MOST MeasureSpec?
So that means everyone who uses the paging library and puts a RV into a NSV has to come up with its own implementation of the NSV? From my point of view this a quite common use case.
Do you have any code example or suggestion how this can exactly be resolved using AT_MOST MeasureSpec?
da...@gmail.com <da...@gmail.com> #4
Hi there!
Take a look at the gist for the solution: "pass down to RecyclerView AT_MOST its own size to work around"
https://gist.github.com/danaimset/abacaa50d746a4537686a08ecc33c1a9
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:
https://gist.github.com/danaimset/6c5c21e918c99eb90c2b9f1e862f2d22
Does anybody know about any other solution?
And don't forget to add android:fillViewport="true" to scrollable container
Take a look at the gist for the solution: "pass down to RecyclerView AT_MOST its own size to work around"
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:
Does anybody know about any other solution?
And don't forget to add android:fillViewport="true" to scrollable container
sc...@gmail.com <sc...@gmail.com> #5
Worth mentioning this SmartNestedScrollView needs list.setNestedScrollingEnabled(true) to work
24...@gmail.com <24...@gmail.com> #6
I tried this and it wasn't the best for me. Instead I prefer to programatically set RecyclerView height to fixed size equal to screen size like this way. important is nestedScrollingEnabled="true" and using custom ViewPortHeightRecyclerView. This class can be customized to take ToolbarsHeight from styleable attrs.
<com.theminte.TheMinte.base.utils.recycler_views.ViewPortHeightRecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:nestedScrollingEnabled="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/topSiblingView" />
package com.theminte.TheMinte.base.utils.recycler_views
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import com.theminte.TheMinte.base.utils.DimenUtils
class ViewPortHeightRecyclerView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : RecyclerView(context, attrs, defStyleAttr) {
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context) : this(context, null)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val displayMetrics = DisplayMetrics()
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getMetrics(displayMetrics)
val toolbarsHeight = DimenUtils.dpToPx(TOOLBARS_HEIGHT)
val params = (this.layoutParams as? ViewGroup.MarginLayoutParams)
val marginsHeight = (params?.topMargin ?: 0) + (params?.bottomMargin ?: 0)
var viewportHeightSpec = displayMetrics.heightPixels - toolbarsHeight - marginsHeight
val viewPortHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
viewportHeightSpec, View.MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, viewPortHeightMeasureSpec)
}
private val TOOLBARS_HEIGHT = 56.0f + 68.0f
}
<com.theminte.TheMinte.base.utils.recycler_views.ViewPortHeightRecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:nestedScrollingEnabled="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/topSiblingView" />
package com.theminte.TheMinte.base.utils.recycler_views
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import com.theminte.TheMinte.base.utils.DimenUtils
class ViewPortHeightRecyclerView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : RecyclerView(context, attrs, defStyleAttr) {
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context) : this(context, null)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val displayMetrics = DisplayMetrics()
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getMetrics(displayMetrics)
val toolbarsHeight = DimenUtils.dpToPx(TOOLBARS_HEIGHT)
val params = (this.layoutParams as? ViewGroup.MarginLayoutParams)
val marginsHeight = (params?.topMargin ?: 0) + (params?.bottomMargin ?: 0)
var viewportHeightSpec = displayMetrics.heightPixels - toolbarsHeight - marginsHeight
val viewPortHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
viewportHeightSpec, View.MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, viewPortHeightMeasureSpec)
}
private val TOOLBARS_HEIGHT = 56.0f + 68.0f
}
24...@gmail.com <24...@gmail.com> #7
I also think the above could be make even better by adding onScroll listener to RecyclerView and then while scrolling up in it, make NestedScrollView To automagically scroll to Top edge of RecyclerView.
en...@gmail.com <en...@gmail.com> #8
I think that the problem not in pagination library , it related to the recycler view with NestedscrollView
int visibleItemCount = this.recyclerView.getChildCount();
if you write this line without NestedscrollView , it will return number of visible items
but in case you add NestedscrollView , it will return number of all items
Try to use ScrollView instead NestedscrollView this will resolve this issue
int visibleItemCount = this.recyclerView.getChildCount();
if you write this line without NestedscrollView , it will return number of visible items
but in case you add NestedscrollView , it will return number of all items
Try to use ScrollView instead NestedscrollView this will resolve this issue
me...@gmail.com <me...@gmail.com> #9
The same issue occurs if you put a RecyclerView inside another RecyclerView e.g Vertical RecyclerView -> item with Horizontal RecyclerView -> item with Horizontal RecyclerView, with paging adapter.
cc...@google.com <cc...@google.com> #10
Putting a ScrollView around a RecyclerView (or a RecyclerView around another same direction RecyclerView) asks the inner RecyclerView to lay out with wrap content.
If you tell RecyclerView to wrap content, you're asking it to layout all of its available content at once. This means you've got a RecyclerView that's not allowed to recycle. This is breaking the primary feature of RecyclerView - the optimization to not do work for offscreen views.
Forcing it to the size of a fixed-size parent like in #6 can work around the problem, though I'm not sure what the nested scrolling is accomplishing in that case. I think a more elegant way to do #6 would be to walk up the tree, look for a specific ancestor (like a NestedScrollView subclass which exposes its measure spec) and use that to drive maximum size.
In the case of a RecyclerView inside another RecyclerView of the same direction, I'd recommend either the same trick, or just combining the adapters into one. In addition to the Adapter, Paging also provides AsyncPagedListDiffer, which can be wired up inside an adapter, alongside other content.
If you tell RecyclerView to wrap content, you're asking it to layout all of its available content at once. This means you've got a RecyclerView that's not allowed to recycle. This is breaking the primary feature of RecyclerView - the optimization to not do work for offscreen views.
Forcing it to the size of a fixed-size parent like in #6 can work around the problem, though I'm not sure what the nested scrolling is accomplishing in that case. I think a more elegant way to do #6 would be to walk up the tree, look for a specific ancestor (like a NestedScrollView subclass which exposes its measure spec) and use that to drive maximum size.
In the case of a RecyclerView inside another RecyclerView of the same direction, I'd recommend either the same trick, or just combining the adapters into one. In addition to the Adapter, Paging also provides AsyncPagedListDiffer, which can be wired up inside an adapter, alongside other content.
da...@gmail.com <da...@gmail.com> #11
It's all about bugs and nobody is going to fix this one. Nobody asked RecyclerView to layout their children at once if it's wrapped with scrollview or nestedscrollview. If the behavior is unpredicted or something like that why there is no throwing exception or warning in xml telling the user that there is no way to put recycler view to another scrollable content?
Could you please fix this bug or provide pagedlistadapter with headers, footers and sections.
It's 100% bug that loadAround is triggered non stop till the latest page. It absolutely clear what's going on with recycler view and it's content and children. But it's ugly to work with such implementation. Epoxy by AirBnb did a lot around recycler view. But there is solution: use single recycler view.
Why you just not saying: okay don't put recycler view in linearlayout from scroll view? Or let us know about a working solution for RecyclerView inside scroll view. Solution does not equal Workaround.
There are too many workarounds along side with layout and widgets from Android :)
P.S.: it's kind of strange to put completely different content like description of my bank account and transactions related to it below in a single RecyclerView:
-scrollview
--linearlayout
---linearlayout with account profile
---recyclerview with transaction (paged list adapter with infinite loadAround calls)
Coordinator layout with scrollable appbar or custom behaviors handling nested scrolls: it's all about Workaround for bugs
What should be fixed: scrollview, RecyclerView or paging library?
Could you please fix this bug or provide pagedlistadapter with headers, footers and sections.
It's 100% bug that loadAround is triggered non stop till the latest page. It absolutely clear what's going on with recycler view and it's content and children. But it's ugly to work with such implementation. Epoxy by AirBnb did a lot around recycler view. But there is solution: use single recycler view.
Why you just not saying: okay don't put recycler view in linearlayout from scroll view? Or let us know about a working solution for RecyclerView inside scroll view. Solution does not equal Workaround.
There are too many workarounds along side with layout and widgets from Android :)
P.S.: it's kind of strange to put completely different content like description of my bank account and transactions related to it below in a single RecyclerView:
-scrollview
--linearlayout
---linearlayout with account profile
---recyclerview with transaction (paged list adapter with infinite loadAround calls)
Coordinator layout with scrollable appbar or custom behaviors handling nested scrolls: it's all about Workaround for bugs
What should be fixed: scrollview, RecyclerView or paging library?
yb...@google.com <yb...@google.com> #12
Actually, the documentation for ScrollView warns about not putting a RecyclerView or ListView inside it:
https://developer.android.com/reference/android/widget/ScrollView
ScrollView is designed to let its children layout completely and ScrollView takes care of showing a portion of it.
So if you put a RecyclerView inside a ScrollView, you are asking RecyclerView to layout all children and it will do so.
You might think RecyclerView could have an arbitrary limit, lets say 10_000 pixels. But how we do we know that is enough? There are various devices + it might be just trying to print a view so it is impossible for recyclerview to make such assumptions.
In terms of not allowing RV inside a ScrollView. It is not that simple either. Many people use RV for short lists just for convenience or maybe to re-use ViewHolders they have elsewhere.
ScrollView could check the first child and warn, or even recursively check all children and warn. But again, that is very tricky as the RecyclerView might have a custom measure implementation that will limit it, or a custom layout manager. Or simply put, it might be scrolling in another axis.
There is simply too many variations to think about and quite impossible to get good coverage without having too many false negatives.
I understand it is annoying when you hit this case but there is limited stuff we can do to safeguard things when the view system is so flexible to do whatever. Obviously we could do more, provide more abstractions to make common things easier, yet it is a resource problem. Unlike common knowledge, we do not have infinite resources.
tl;dr; There is nothing to fix here. If you ask the RecyclerView to layout all of its children, it will layout all of its children. If you want to limit that, you should use the APIs provided in the view system to do so.
ScrollView is designed to let its children layout completely and ScrollView takes care of showing a portion of it.
So if you put a RecyclerView inside a ScrollView, you are asking RecyclerView to layout all children and it will do so.
You might think RecyclerView could have an arbitrary limit, lets say 10_000 pixels. But how we do we know that is enough? There are various devices + it might be just trying to print a view so it is impossible for recyclerview to make such assumptions.
In terms of not allowing RV inside a ScrollView. It is not that simple either. Many people use RV for short lists just for convenience or maybe to re-use ViewHolders they have elsewhere.
ScrollView could check the first child and warn, or even recursively check all children and warn. But again, that is very tricky as the RecyclerView might have a custom measure implementation that will limit it, or a custom layout manager. Or simply put, it might be scrolling in another axis.
There is simply too many variations to think about and quite impossible to get good coverage without having too many false negatives.
I understand it is annoying when you hit this case but there is limited stuff we can do to safeguard things when the view system is so flexible to do whatever. Obviously we could do more, provide more abstractions to make common things easier, yet it is a resource problem. Unlike common knowledge, we do not have infinite resources.
tl;dr; There is nothing to fix here. If you ask the RecyclerView to layout all of its children, it will layout all of its children. If you want to limit that, you should use the APIs provided in the view system to do so.
mo...@gmail.com <mo...@gmail.com> #13
The solution in #6 fixes the Paging Problem but creates another one. I have a similar situation as #11, so the RV scrolls under the ProfileData and doesn't act as a big scrolling container.
I could put that ProfileData inside the paged list but I need another API Call to get the data. Therefore managing the views, states, errors and the paged list from the DataSource will lead to a very big, not flexible, unmaintainable and generally ugly code.
I agree that it's mostly a RV problem but in Normal cases that's something you can go with. Because if you want to draw 1k items it will do it. But here we talk about INFINITE items. Therefore Paging has to deal with that issue.
I could put that ProfileData inside the paged list but I need another API Call to get the data. Therefore managing the views, states, errors and the paged list from the DataSource will lead to a very big, not flexible, unmaintainable and generally ugly code.
I agree that it's mostly a RV problem but in Normal cases that's something you can go with. Because if you want to draw 1k items it will do it. But here we talk about INFINITE items. Therefore Paging has to deal with that issue.
yb...@google.com <yb...@google.com> #14
This is neither a RecyclerView nor Paging problem. It can be considered a missing feature where there is no easy way to do this w/o writing a custom adapter but you can use AsyncPageDiffer and offset change events manually to merge the data.
cc...@google.com <cc...@google.com> #15
Recent update in this space, MergeAdapter is being added to RecyclerView, which allows you to concatenate multiple independent RecyclerView adapters: b/147833132
This will be way that paging recommends to display headers and footers (including dynamic ones like loading spinners or retry error buttons) in a single contiguous list, for a single RecyclerView.
This will be way that paging recommends to display headers and footers (including dynamic ones like loading spinners or retry error buttons) in a single contiguous list, for a single RecyclerView.
na...@awantunai.com <na...@awantunai.com> #16
MergeAdapter/ConcatAdapter does not help is second recycler view uses GridLayoutManager and first view is a horizontal recycler view
Description
Version used: android.arch.paging:runtime:1.0.0-alpha5
Devices/Android versions reproduced on: Neuxs 5x Android version 7.1.2
I am using the paging library for loading items using a next page link. The problem is, that the `PageKeyedDataSource` is loading an infinite amount of items (of course till no next page is available anymore) without any use interaction (loadAfter is called endless). This happens only when the `RecyclerView` is wrapped into a `android.support.v4.widget.NestedScrollView`. If the `RecyclerView` is in a different container everything works fine.
I could also reproduce the issue in the samples from github (
Thanks for your help up front