I have situation where in long list I remove item at specific position. Now I update it in my variable that holds the list, but I also need to notify adapter.
I would like to avoid using notifyDataSetChanged() since in my opinion it wastes resources in this case.
So I use:
notifyItemRemoved(homeItems.size - 1)
But what happens here is that when I shoot this function, it scrolls my list to the beginning. Since I am using pagination in my app, this looks very bad. I want to stay on the same position I scrolled to. Is it possible to avoid this animation?
If not is there any other way to solve this situation by notifying adapter that only 1 element changed?
You can disable animations by adding following line to recycler view
recyclerView.itemAnimator = null
This will disable all the default animations
For java
recyclerView.setItemAnimator(null);
Related
Is is possible to have race conditions between the notify* methods of a RecyclerView.Adapter and scrollToPosition (and smoothScrollToPosition) of the RecyclerView itself? If so, how can I force the scroll to happen strictly after the notify has been applied?
In a bit more detail: I have a RecyclerView with an adapter that frequently is updated with new items (which may or may not overlap with the previous items). Also, whenever I set new items I also want to set the scroll position to a specific item. To that end, I first update the items inside my Adapter and then scroll the RecyclerView.
However, more often than not the scroll position will be wrong after this process. Also, if I then issue another smoothScrollToPosition command without changing the data, the scrolling is weird: It sometimes goes in the wrong direction, etc. After this second scrolling, the position is always correct however. So, it seems that something goes wrong the first time and the RecyclerView catches and corrects that error on the second scroll.
Also, the errors are slightly different when I use notifyDataSetChanged from when I use DiffUtil.
Now I've read in this response by Yigit that notify* is basically asynchronous, so I suppose there can be a race condition between them and the subseqent scrollToPosition - is that correct?
Finally what can I do to establish a strict ordering, so that the scroll is only called when all ViewHolder updates triggered by notify are done?
I have a dialog with RecyclerView of IDs in it. While I was choosing an id it changes its background. I did it by replacing adapter where I am putting newly selected position. And in my adapter item layout was chosen by its position where if equals to selected, it has another layout.
So after resetting a new adapter to recycler it losses current scroll position. I tried to use scrscrollToPosition, but it still not perfect, due to the situation that scrolled position is always on a beginning of RecyclerView.
So as I understand the problem I need to remember reference or some other scrolling data for setting it on the new adapter.
So If someone knew relevant RecyclerView methods or good practice for this problem, it would be nice =)
I don't think that here I need some code, cause it more practice question, but if someone need it I would add it.
Update: Meantime I found this method for getting offset of RecyclerView but still looking how to use this data in new adapter.
int offset = recyclerViewDialog.computeHorizontalScrollOffset();
I'm using recycler view with grid view (every item contains a grid) with thumbnail images after adding images in view it start uploading, and i need to change some values (status) in model at the time of start and finish upload.
What I'm currently doing is change values in model and call notifyDataSetChanged, but it causes to slow down application (hang some times) because it updating every child of list :(
Can any one help me with this?
Call notifydatasetchanged() for particular Gridview adapter only. Don't call notifydatasetchanged() for complete recyclerview adapter.
Try setting it again to the adapter.
gridview.setAdapter(your adapter)
-passing your new list to your adapter.
I believe notifyDataSetChanged updates all of your values regardless if they have a change or not that is why it is slow. I suggest you try using notifyItemChanged(int position) instead.
According to recyclerview docs this is what notifyDataSetChanged does:
This event does not specify what about the data set has changed, forcing any observers to assume that all existing items and structure may no longer be valid. LayoutManagers will be forced to fully rebind and relayout all visible views.
Old question but similar to what I'm experiencing.
RecyclerView is usually incredibly fast when changing list details. But manipulating a lot of images can really slow it down if you're not careul.
I'd recommend you try removing the images and repeat it so you can see if that is just as slow. I suspect this will be a lot faster.
If so, make sure you're handling the images off the UI thread. The Android docs recommend you use a library such as Glide which also handles sub-sampling the image to make sure it's the right size.
Hope that helps!
I have a RecyclerView with setStackFromEnd(true) representing a chat list. And I want to load older messages when the list is scrolled to the top. I managed to do this using onScrollListener.
But when I add items to the adapter with messages.addAll(0, aListWithNewMessages) (messages is data set for adapter) and call notifyDataSetChanged(), new list items (as expected) appear before the existing ones and shift them down (not the experience a user wants), and I want to add them silently so a user shouldn't see it.
So my guess for how to tackle this issue is to scroll list to somehow previously saved position.
I understand that this is not a bug or an unexpected behavior, so please help to sort it out.
Thanks
Try being more specific. Instead of calling notifyDataSetChanged() use notifyItemRangeInserted or similar RecyclerView methods. That will allow RecyclerView to know what to do and will provide much better UX.
Is there a way to call BaseAdapter.notifyDataSetChanged() on a single element in the adapter.
What I am trying to do is update the data and reflect those changes in the containing ListView. The problem is that sometimes the change is so small that it seems ridiculous that I have to refresh the whole view rather than the single item in the view that has been updated.
I am not aware of such method. If it's really important, you can always find individual item view to update. But I don't think that it worth it as Android is pretty efficient in updating list views. So it will not do much extra work (definitelly not going beyond items currently visible on the screen).