I have the following structure in the LazyColumn:
item {
// complex layout with long time of recomposition and inside the HorizontalPager
}
items(list) {
// item content
}
The issue is when I scroll down until the first item becomes invisible and scroll back, every time the first item appears on the screen it freezes.
I know that lazy layouts recompose their items unlike the RecyclerView which just binds data to a ViewHolder. But in this case the lazy layout works awful. Recomposing my first item takes too much time to provide a smooth scroll to the top.
Also I've mentioned in the structure that my complex layout is inside the HorizontalPager, which is a lazy layout too. Swiping this pager is not smooth either.
How to handle this? Is there a way to cache or prevent recomposition in a lazy layout? Something like RecyclerView binding?
Related
How can I implement this kind of UI, where we have two recyclerViews. One scrolls horizontally and the second one vertically. when the second one scrolls first one also scrolls top together.
I tried to implement using NestedScrollView, but I had to make second recyclerView height wrap content which causes recyclerView not recycle.
The second way that I tried was having one recyclerView. And adding horizontal recyclerview as a header. The problem was to save header recyclerview scroll state when navigation. And there had been crashes when loading next page (paging 3) in header recyclerView.
The question is: Is there any optimal solution for this kind of ui?
In cases, Like this, you don't have to use 2 RecyclerView and you also have to avoid using RecyclerView insideScrollView. instead of this you have to use one vertical RecyclerView with multitype view Adapter.
in this way, you are going to have 2 different ViewHolder one of them is a horizontal recyclerView (your top item) and the other one is your other items.
for learning multitype adapter you can see this:
How to create RecyclerView with multiple view types
and for a horizontal recyclerView inside a vertical RecyclerView you can see this :
https://medium.com/#ashishkudale/android-list-inside-list-using-recyclerview-73cff2c4ea95
you have to combine these 2.
I could not understand the meaning of "header" where you said "adding horizontal recyclerview as a header" but if you did what I told and the problem is the state of inner Horizontal recyclerView, I think probably you are calling setAdapter method of horizontal RecyclerView in OnBind() method of your vertical recycler view, it is a common mistake that I have seen in many tutorials.
if you have done this mistake , try to call setAdapter of your inner recyclerView in the constructor of its viewHolder and just update the list using yourHorizontalAdapter.notifyDataSetChanged() in onBind() method of VerticalRecylerView,
and if its not the case and your recyclerView is completely destroying see this link :How to save RecyclerView's scroll position using RecyclerView.State?
I have to implement a transition of either a viewpager o a recyclerview, not sure yet which could fit better. The idea is to expand de ViewPager or Recycler and show more information when this is expanded and less information when is collapsed.
Expand and collapse with MotionLayout is quite easy however I cannot find the approach for animate and change the content shown in each element of the the adapter.
is it posible to animate the content of an adapter simultaneously?
I an ugly solution for you. I use a recycler-view that contains some motion layouts. There is an expanded state and a collapsed state, we only want one expanded at a time.
A method to close positions in the fragment/activity
fun collapseMotionLayout(positions: IntArray){
positions.forEach { position ->
recyclerView.findViewHolderForAdapterPosition(position)?.let { childView ->
//transitionToEnd() or transitionToStart() or toggleUI() or whatever
(childView.itemView.findViewWithTag("motionlayout") as? MotionLayout)?.collapse()
}
}
And then a fragment/activity call back in the motion layout's TransitionListener that you'll define in the viewholder (we use a custom view)
tListener = object: TransitionListener{
override onCompleted(){
callBack.invoke(positionsForAnimation())
}
}
I only see this collapse a single motion layout at a time. I have found that multiple motion layouts running simultaneously will will cause performance issues.
Default RecyclerView feature is to load only those items which are visible and load rest of the items as needed when user scrolls the list.
But my requirement is to load all items at once.
Any idea how to achieve this.
I am loading a Book and each page has multiple images for every line.
I am loading one image per item and I need to implement auto scroll feature for which I need to calculate whole recyclerview height.
I think instead of changing the default behavior of recyclerView if its possible use listView/gridView (until and unless you need StaggardGridView of recyclerView)
Just keep Recyclerview inside NestedScrollView. In simple first all the views regarding recyclerview items, that of cards is set to NestedScrollView and the things goes perfectly.
This is a question regarding the use of Android Transition API.
I am trying to animate the height change of a list, just like a dropdown menu.
I tried 2 approaches
Use a RecyclerView and animates its height change
Use a ScrollView > LinearLayout hierarchy and animates ScrollView's height.
The 2nd approach works perfectly.
But the 1st approach has a serious glitch - when the collapse transition starts, items disappear immediately.
By looking at the below GIF you can observe clearly the difference:
To be exact, items' visibility changes at the moment I change RecyclerView's LayoutParams, without waiting for the transition to finish, whatever it is expanding or collapsing
Code
I have created a minimal project on Github.
If you just want to look at the code, here is the MainActivity.
Question
Is it possible to achieve ScrollView's effect with a RecyclerView?
If yes, how?
My Idea is to do the transition of all the recycler view rows individual rather than the whole RecyclerView:
So when collapsing iterate through each ROW of a RecyclerView and do a transition. Remember to check for null if some rows are recycled they may return null. So after that collapse the whole recyclerView.
And like wise for the expanding do the same for the views.
This issue is cause by RecyclerView has many views with it but Scroll View has only one View nested in it.
Currently, I am exploring the option of displaying data from a database by swiping left to right and also allowing users add and remove data from any position in the data array.
I found out that there are 2 possible solutions to do this. One is a RecyclerView with horizontal scroll and the other is a ViewPager with a FragmentStatePagerAdapter .
Which is more efficient? In terms of Memory usage and Ease of implementation?
Thanks.
I would say they are comparable in terms of memory usage and ease of implementation. Where they differ most is in the interaction they provide to the user.
ViewPager is designed to show one item at a time. The visible item takes up full width of the ViewPager. You can only swipe one item at a time and scrolling always snaps to showing one item in the centre – you're never left in an in-between position partially showing two items.
RecyclerView with a horizontal layout manager on the other hand can have items of any width – you could be showing many items at once or you could have items wider that RecyclerView's width or you could match their widths to mimic ViewPager. You can freely scroll – you are not limited to one item width or RecyclerView's width, you can do a fling gesture to scroll big distances. And there's no snapping – when the scroll finishes there's no aligning items to the centre or any of the sides.
As you see there are a few differences. I would recommend you to choose your widget based on the UI you want to achieve. If you want ViewPager's behaviour (one item visible at a time, swipe limited to one item and snapping to show the full item) then go with a ViewPager. It's possible but not trivial to replicate this behaviour using a RecycleView. I would definitely say it is way more difficult to use RecyclerView if you want to make it behave like ViewPager. Conversely it's pretty much impossible to customise ViewPager's behaviour, so if that's not what you want then you definitely should use a RecyclerView.
In term of ease of implementation (this is just my own opinion),
ViewPager is good for displaying the list of data that is not required often add and remove since PagerAdapter can't notify each specific item that it is removed or added it can only call notifyDataSetChanged() which notify that all set of data has been changed. Therefore, it is hard to handle the animation when the item is added or removed.
While in RecyclerView, RecyclerView.Adapter has methods like notifyItemInserted(int position) or notifyItemRemoved(int position) to notify that specific the item is added or removed and, the animation when item is add or remove is already handle when you called those method.
Moreover, right now it is very easy for RecyclerView to mimic the ViewPager behavior by using SnapHelper. There is PagerSnapHelper, and the behavior of ViewPager can be obtained with just a few lines of code. You can contact me if you want the code.
There is no comparison between this two. basically in ViewPager you can scroll only one item at time (either left or right), and in RecyclerView you can scroll to any index. it all depends on your requirements how you want to use it. you need to develop fragments for ViewPages, one for each page. as in RecyclerView you will have a item which will be used by adapter. both of them are easy to implement. there are numerous examples on both of them, you can have a look and get started.