I have a list of elements in a recycler view that are generated dynamically using data binding. Each element has a bottom view that is initially set to View.GONE, however once a user clicks the element and the view is expanded, the recycler view automatically scrolls back to the top of the list. Conversely, if the view is expanded and then clicked again to collapse, the recycler view scrolls to the top of the list again. I have tried keeping track of the ID's of the elements for the adapter (again using data binding), setting focus to the child element when they expand or collapse, and using binding adapters to animate the expand/collapse itself.
My suspicion is that the adapter in the recycler view is receiving a onNotifyDataChanged() alert when the height of one of the child changes, rendering an additional view (still inside one of the children though, not a separate child in the list), and automatically scrolls to the top. Is there a way to override this? Does anyone know what else might be causing the list to snap to the top when one of the elements is clicked -> expanded/collapsed?
So I found the solution to my issue in case someone encounters something similar. I actually ended up finding this answer: RecyclerView notifyDataSetChanged scrolls to top position
and the second solution involving the staggered layout manager was the route I went with, since I want to be able to wrap the content. My suspicions were correct that it had to do with the changing height of the elements in the recycler view. The expandable item's parent wrapped content, so the recycler view was forced to recalculate the size of the item once the expandable portion appeared/disappeared (at least that's what I got out of it).
Related
I am using recycler view with linear layout manager, based on some logic I am hiding/showing a view inside recycler view item.
Issue Problem occurs when I scroll, I can see some gaps in between recycler view item, which are random when scroll. If I hide the view always , then there is no issue, but I need to show and hide based on some logic and when implemented the gaps are coming as well.
Assumption One thing I am sure of is that the issue is there because of hiding/showing a view.
I'm trying to design a row list using RecyclerView like Android TV ↳ android.support.v17.leanback.widget.ListRow. I'm able to design list with title but not row list. Can anyone help me?
Please Follow this Link for
Recycer view like play store
Use Two RecyclerView Outer Recycler is vertical and Second horizontal recycler is item of first recycler View
All you need is to call mInnerRecycler.setNestedScrollingEnabled(false); on your inner RecyclerViews and use Horizontal scrollview as root of mInnerRecyclerView
Explanation:
RecyclerView has support for nested scrolling introduced in API 21 through implementing the NestedScrollingChild interface. This is a valuable feature when you have a scrolling view inside another one that scrolls in the same direction and you want to scroll the inner View only when focused.
In any case, RecyclerView by default calls RecyclerView.setNestedScrollingEnabled(true); on itself when initializing. Now, back to the problem, since both of your RecyclerViews are within the same ViewPager that has the AppBarBehavior, the CoordinateLayout has to decide which scroll to respond to when you scroll from your inner RecyclerView; when your inner RecyclerView's nested scrolling is enabled, it gets the scrolling focus and the CoordinateLayout will choose to respond to its scrolling over the outer RecyclerView's scrolling. The thing is that, since your inner RecyclerViews don't scroll vertically, there is no vertical scroll change (from the CoordinateLayout's point of view), and if there is no change, the AppBarLayout doesn't change either.
In your case, because your inner RecyclerViews are scrolling in a different direction, you can disable it, thus causing the CoordinateLayout to disregard its scrolling and respond to the outer RecyclerView's scrolling.
Notice:
The xml attribute android:nestedScrollingEnabled="boolean" is not intended for use with the RecyclerView, and an attempt to use android:nestedScrollingEnabled="false" will result in a java.lang.NullPointerException so, at least for now, you will have to do it in code.
RecyclerView can check View Type for return header or item. And use layout manager for manage how to item scrolling direction.
RecyclerView (vertical scrolling)
- item -> RecyclerView (horizontal scrolling) check view type is header or item with condition example : is object has type header
Ref : Google play store like interface using recycler view
I have a vertical recyclerview with multiples types like horizontal recycler inside.
My problem concern an item not visible (so not bind yet) at the start of the fragment (i.e maybe the item number 6 ou 7 of the list).
This item is an horizontal recycler view and when I first scroll to the bottom I have a lag when the item is binding...
I already optimzed my xml to have just 1 parent view
I already set fixed size to true
I already also setNestedScrollingEnabled(false)
😕
So, I tried to use pretech item count from this article (
https://medium.com/google-developers/recyclerview-prefetch-c2f269075710) but I don't see the difference. (maybe I don't implement it correctly)
I am asking if I can really bind this item (it's an horizontal recycler) when he is not visible...
I want to keep the main recycler and don't inflate manually a linear layout because I have a lot of view types ( I tried but the solution was pretty ugly).
Thanks in avance
My layout is a bit complex.
I have a SwipeRefreshLayout in which I host a ListView. Whenever the user drags the Listview's top, the SwipeRefreshLayout performs a refresh. I also listen for the last visible item of the ListView to load next page of records (Endless scroll)
In the list's adaptor I have 2 views that I am using. The first one will only be visible in first row, the other view will remain the same for all other rows.
What I want to achieve:
On top of the row with position = 1 I want to have a sticky header. This means that when I scroll Up, the header will scroll to the top of the screen and will remain in there.
This sticky header will only be at one row
if possible I'd like to use a simple implementation as my layouts and adapters are already complex enough.
Waiting for your suggestions.
I didnt quite get your question the first time, heres the answer attempt round 2.
In your layout add an empty viewgroup (whichever you prefer, though linearlayout seems to work just great), add a scrollListener to your listView and check the position of your sticky view. If its top anchor is below (meaning its visible in the listview) the top of the screen you set the viewgroup visibility to gone, if the top anchor is either touching the top of the screen or below it, you add that view or one just like it to the viewgroup and set its visibility to visible.
You can adjust the position 2 view visibility accordingly to allow for this change to appear seamless. Can help you a bit more once you have some code and are on your way with this change.
I have a ListView which has overlayed on top of it another view which I call a Header. This header can be of various heights.
On ListView's dataset, I insert in a blank row, and programmatically set the height of this row to be the height of my Header view. This way when the ListView loads, the row at position 1 (the actual first row of data) is lined up to the bottom of the header. I do this so I can set the Header view as partially transparent and when the user scrolls they see the rows of data mix with the transparency of the Header view.
Now I have one use case where I can navigate to this list and a given row will be selected. What I've done is call setSelection with position X. This will automatically scroll my ListView so that the top of row X is at the top of the list. However, my Header view still obscures this. To compensate I call scrollTo. These two pieces are something as such:
listView.setSelection(selectedRowPosition);
if(hasHeadersEnabled()) {
listView.scrollTo(-headerView.getMeasuredHeight).
}
When I call these lines of code, my ListView looks as I would expect. The selected row's top is to the bottom of my HeaderView. The problem I run into is that as soon as a user touches the ListView, the scroll position jumps so that the selected row's top is at the true top of the ListView (aka the Header view's top).
My question is, after you setSelectedRow on a ListView, does the ListView always expect that row's top to be the ListView's top when it starts consuming the onTouch events for scrolling? Is there another way to accomplish what I'm hoping to do with this code? I've tried scrollTo and scrollBy and both have the same effect.
So I should have looked at the API harder. Found the answer to my question.
I need to use setSelectionFromTop instead of the combination of setSelection and scrollTo. Here is the sample code:
listView.setSelectionFromTop(rowPosition, headerView.getMeasuredHeight());