I have a RecyclerView and one item row needs to be updated like every second (SeekBar). So I call NotifyDataSetChanged once I update the data in the list. UI gets updated but the issue is that the RecyclerView scrolls so that this particular item is either at top or bottom of the screen.
I don't want RecyclerView to scroll.
// Update Data
mData.set(mData.indexOf(cardData), cardData);
// RefreshView
refreshView() {
runOnUiThread(new Runnable(){
notifyDataSetChanged();
}
);
You can update one item using notifyItemChanged(position); and u wont update all data in adapter, you will update only certain item
It's better to use the other notify methods from the RecyclerView.
For your usecase only swap out one item in your Adapter instead of all items and use notifyItemChanged(position).
This will be faster, the View won't scroll and if you ever will add an animation this will only work if you don't use notifyDataSetChanged
I got it working. I was having a card view above the recycler view.I just removed it. Now the whole screen is a recyclerView and I cannot see any auto scrolls.
Related
I have a recycler view with a delete button for every item,and the data for the recycler view is a Live Data list.
Basically im observing the list and when i delete an item i just pass the adapter again to the recycler view with the new list in order for the list to update,like this
viewModel.loadBasketItems().observe(viewLifecycleOwner, {
adapter = BasketFragmentAdapter(it, viewModel, requireContext())
recycler.adapter = adapter
})
My first problem with this is that the image jumps to the top of the list every time i delete an item,because the list is created again completely
My second problem with this is i don't think this is very efficient.
What's the best method to update the recycler view after you change something
You shouldn't be resetting the adaptor like that. Keep the adaptor the same, but call notifyDataSetChanged(). This tells the adaptor its data has changed, which will tell the recycler view to redraw itself. What you're doing makes the recycler view assume it has a whole new adaptor and needs to drop all info about the old one.
Even better would be to call one of the more specific notify functions on the adapter that tell it what elements changed, but the general one is good enough until you see perf issues.
I have a recyclerView and list of items. Items are observed in viewModel, adapter gets a changed list whenever list in viewModel changes.
However, I have a problem when updating certain item views in existing list item - these changes happen, but to see them I have to scroll up or down a bit. In view holder I have all necessary if/else cases what to update according to item values. Is there a way to update item view instantly, without having to scroll?
You can call adapter.notifyDataSetChanged() function to force the adapter to redraw all items again.
you should use adapter.notifyItemChanged(int indexOfChangedItem) or adapter.notifyDataSetChanged() after you changing any item of the list.
the first one will update 'all' item viewes but the second one will update only the view that you passed it's index.
I'm using adapter.notifyDataSetChanged(). I'm just curious if I can refresh a list view item without scrolling it off screen when call that method.
adapter.notifyDataSetChanged() will automatically call getView() for every row currently at least partially visible on the screen.
You don't have to scroll anything.
From the official documentation
notifyDataSetChanged(): Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
So, in other words , whenever you call that method, is being called the getView() method and refresh the content of your changed slots.
How can I stop RecyclerView from scrolling to the bottom of the list whenever I add items?
Even when I insert something at the top of the list and call notifyDataSetChanged or notifyItemInserted the list scrolls to the bottom.
The one feature that works as expected is notifyItemRemoved(index)
I think I was calling notifyRangeInserted() with the entire list and that was scrolling to the end of that range.
If you're having similar issues, just cut the Adapter functionality back to its bare essentials and build up from there.
The problem was I had an item in the list, a ProgressBar to indicate that data was loading, but when the new items loaded I added them to the list, this moved the "focused item," the ProgressBar down and if there were enough items to move it off the screen then the RecyclerView would scroll down to keep it on screen. The problem being 1. I didn't want it to maintain "focus" and 2. The very next thing I did was remove the ProgressBar from the `Adapter.
So the solution is to remove the ProgressBar or other items before adding items earlier positions in the Adapter.
I have vertical RecyclerView for scrolling group of items and horizontal RecyclerView in each ViewHolder in order to scrol items inside of these groups. They are populated from database. Whenever item content is changed (user tap something or new data come from network) it is written to database and then notifyDataSetChanged() is called for the group cursor. I check if it is the same group in onBingViewHolder() and update items only if it is. But horizontal RecyclerView is scrolled anyway to the first item.
How could I prevent this behavior and why does it happens ?
BTW I'm writing result of this check in 'onBindViewHolder()` to the log and I can see that it is the same item.
Thanks.
RecyclerView creates new ViewHolder in order to perform animation. setItemAnimator(null) solved my problem.