Nested RecyclerView scrolls to the first item on NotifyItemChanged - android

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.

Related

Android Nested RecyclerView update items

What's my Goal?
I need to update a nested Recycler View and all it's content, if a Switch changes it state (isChecked true/false) AND any other Item within the RecyclerView has the Same Category, then Update each of the Item's with the same Category to Disable the Switch. I need to disable the Switch Button, to prevent the User from selecting more than 1 Item of the same Category.
What's the issue?
My nested Recycler View will update my RecyclerView correctly, if the RecyclerView get's initially loaded, displayed and if I don't scroll even a nano-centimeter. But if I scroll the RecyclerView, nothing will update anymore... sometimes it does update the WRONG RecyclerView and only 1 Item... so no matter what Category I switch the (isChecked) to 'true', it will update 1 Item in a different RecyclerView (Everytime the same Item, which I checked before I started scrolling)
How is it implemented so far?
I have a RecyclerView which has an TextView on Top and a nested RecyclerView beneath it. This Nested RecyclerView has an Item, which basically consists of an Id, CategoryType, Text and CreationDate.
I'm using DiffUtil to do all the hassle for me (notifyDataSetChanged, notifyItemInserted... etc).
val diffUtil = CategoryDiffUtil(_categoriesWithinRecyclerViewAdapter, inNewCategories)
val diffResult = DiffUtil.calculateDiff(diffUtil)
diffResult.dispatchUpdatesTo(this)
I'm sending a new List of Categories to the "setData" functionallity within the FirstLevel RecyclerView, which calls each Nested RecyclerView's "setData" functionallity with the Categories for the Day. To know, which Item's Switch needs to be disabled, I store the Selected Category-Type in a List within the Nested RecyclerView where I recently Checked (Switch.isChecked == true) a Category. Every FirstLevel RecyclerView has an List of Reference to Adapters of the Nested RecyclerView beneath him. This is how I'm able to call "setData" or generally update the Nested RecyclerView (See Code for adding Adapter to FirstLevel RecyclerView to update beneath Nested RecyclerViews later)
if(_adapters.isEmpty() || !_adapters.any { it.first.contentEquals(inNewCategories.getCreationDate()) }){
_adapters.add(Pair(inNewCategories.getCreationDate(), _adapter!!))
}else if(_adapters.any { it.first.contentEquals(inNewCategories.getCreationDate()) }){
_adapters.removeIf { adapter -> adapter.first.contentEquals(inNewCategories.getCreationDate()) }
_adapters.add(Pair(inNewCategories.getCreationDate(), _adapter!!))
}
What have I tried to fix my Issue?
Tried to use nestedRecyclerViewAdapter.notifyDataSetChanged(), but it didn't help (does have the same issue mentioned in "What's the issue?").
Added Logs to ensure, that the Nested RecylcerView Adapter's are correctly stored and replaced. Ensure that the DiffUtil get's triggered if something changed (It does, and it know's exactly which item's needs to be updated)
I Tried to use Compose LazyColumn + StickyHeader to see if this changes something. But I'm still to inexperienced with it, that's why it was running far slower than my Nested RecyclerView and I gave up (for now) on using it (compose).
Not sure if I explained any crucial detail, but I hope someone could help me.

Recycler view starts auto scroll when new list is added

I have an problem with implementation of recycler view.
I'm using listadapter with recyclerview.
Everythings work perfectyl unitl I'm changing arraylist items order.
When I'm changing the items order and submit it to adapter the recycler view makes scroll.
For examle if i reverse the arraylist , its scrolling to the bottom.
How to disable auto scrol or keep recyclerview scroll position when the sort orders is changed.
There are two possible ways to solve this issue. Please try them :-
You can use notifyItemRangedChanged(fromIndex,toIndex);.
You can use RecyclerView.scrollToPosition(0); when sort orders are changed.
Thank you!

RecyclerView item view updates after scrolling up or down

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.

NotifyDataSetChanged refreshes RecyclerView but scrolls as well.

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.

Get RecyclerView to stop scrolling when I add items to the Adapter

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.

Categories

Resources