Notifydatasetchanged() between adapters - android

I have 2 recycleviews and both of them have a number of icons. I also have a list that contains a number, which is the number that represents which icon has a background that shows it has been clicked.
Now, the problem is that I only want one icon marked, with this I mean 1 item in total of those 2 recyclewviews. The way I've tried to do this is having a json that saves a number that determines which recycleview should have a marked item, if it doesn't have the number of the recycleview, then the background is the normal one, that way only one recycleview has a marked item.
The problem is that for that to work I need to call the method Notifydataserchanged() on the other adapter so the marked background dissappears, and the easiest way of doing that is putting the other adapter on the constructor. The problem with this is that only works for one, because since the other is declared before you can't construct it with the adapter that comes after it.
I've seen way of doing it with listeners/interfaces made in the activity and then
moved to the adapter itself so you can just call those methods, but it hasn't worked for me.
Any ideas? Thanks

Related

how to update the data in specific position in the recyclerview without notifying the whole item? (Ex. text, image etc)

I need the functionality to update the data in the item in the recycler view. right now, If we notify the whole item it shows some fluctuation and we want to avoid refreshing the whole item on the UI.
I am using the ListAdapter with diff utils.
There are many ways to achieve your goal.
self-managing items. Adapter doesn't know anything about content of the items, it only puts items into RecyclerView. Content is managed by the item itself, so your problem is already solved.
custom adapter. Adapter has intricate knowledge about every item and can update selected ones accordingly.
AsyncListDiffer You can add differ to your adapter and it will take care of not updating parts that need no update.
Without seeing your code, we can't tell which way would be the most appropriate for you, but I guess adding differ is the simplest on already working code.
You need to create custom Adapter:
https://developer.android.com/develop/ui/views/layout/recyclerview
If you're talking about updating specific list items, and you're not using a DiffUtil (which will handle it for you) then you need to call the appropriate notify* method on your Adapter.
They fall into two categories, item change events (where the item list stays the same, but the displayed data for one or more of those items changes) and structural change events (where the actual list of items changes in some way, e.g. insertion/removal, or reordering).
I'm assuming you just want to update the displayed data for an item, so you should use one of the notifyItemChanged or notifyItemRangeChanged methods to inform the adapter that a certain item (or range of items) needs to update. If any of those items are currently being displayed in a ViewHolder, then onBindViewHolder will get called again for those items - which is where you set all your text, images etc depending on the item you're displaying. So you'll update them with the current data.
Both those methods have a version that takes a payload Object/Any, where you can pass in some data to be used in a partial bind - basically, onBindViewHolder can receive that data and be smarter about the update, which means you can avoid things like reloading images, etc. by passing in some stuff and checking for it during the binding process. More info about that here in the other version of onBindViewHolder you can implement, if you need to.

How can I prevent notifyItemChanged() from killing the ripple effect when selecting an item in a RecyclerView?

I have a RecyclerView and I would like to allow users to select views using a long press. This works fine except that the ripple effect is terminated as soon as I call either notifyItemChanged() or notifyDataSetChanged in order to indicate the selection. How can I prevent this from happening?
Note, this question has been asked before (Example 1, Example 2). The answer to those questions has been to use notifyItemChanged instead of notifyDataSetChanged. I have tried both of these and it does not change the behavior for me.
There are two versions of notifyItemChanged() method. One takes only position and the other one takes position and a payload.
And in my case the first one broke the ripple effect, while the second one worked. At least when I passed the object that just has been changed as the payload.
a) add DiffUtilCallback to your adapter
b) make sure what your areItemsTheSame method compare items by id and not by content.
Because if it compare by content, it thinks what you remove previous cell and insert new, and kill ripple effect.

Access Adapter items of Recyclerview

I'm using Recyclerview to show a list. I want to delete some items like IOS. In my listview template I have added a button to delete item which is invisible by default. In my activity I have another button attached at bottom (Not part of listview) and on tap of this button I want to make all delete buttons of listview visible.
My Question is how can I get reference to all delete buttons of listview in activity and is it the right way to do this?
Thanks
Assuming you have ViewHolders set up, you already have references to all the buttons in your list. All you have to do is to make them visible for every item in the list with a simple loop.
In case you haven't implemented ViewHolders I suggest you check out the documentation and take a look at some simple tutorials on how to use them.
On a side note. If I understood correctly you're making a bottom tab for your app and since you referenced iOS I gotta say this; Remember that Android and iOS are two unique operating systems with their own ways of handling things. Check out Googles pure Android documentation.
In your question title you say RecyclerView, but in your text you say ListView. The solution is similar either way, but it's best to be perfectly clear what you're doing.
In either case, there are at least two different solutions.
First, you could use a boolean flag to determine if all the the item buttons should be showing or not. You check this flag at the time the item view is inflated or created and toggle the button accordingly. If the boolean flag is ever changed, the easiest thing to do is tell the RecyclerView/ListView that the underlying data has changed and to redraw all the views. Call notifyDatasetChanged on the adapter.
The other thing you can do at the time the item buttons should change is iterate all the visible item views, find the button, and change its visibility. With RecyclerView, you can do this, and with ListView you can do this.

Show / Hide Listview SectionIndex on demand

i implemented a listview which implements SectionIndexer ...
everything fine so far.
Normally the items are sorted by Name, but i also offer the option to sort the list in a different way - by distance (from the user to the objects).
So, when the list is sorted the 2nd way, i want to hide the previously generated SectionIndex.
I'm just not able to do so.
I tried, re-writting most of the methods,
I tried it with a separation in the Constructor (clear why it doesnt work, it doesnt get called a second time)
I even tried it with implementing a second listadapter, and just using a different one? Even in this case the SEctionIndex is shown! I really don't understand this one.
So would be really great, if anyone knows whats going on :)
thanks a lot, mike
Your observations are correct. Let me tell you first why the constructor never gets called the second time. SectionIndexer are a special kind. They create the index only once for a particular set of data and re-use them on that adapter. The bigger issue which I had come across was when the underlying data changed for the adapter, the sectionIndexer still remained the same.
Check my Question and the answer there.
Coming back to your query here.
If you change the orientation after selecting the second option, you would observe that the constructor will get called and you will be able to re-populate the sectionIndex again. So basically you need to call onSizeChanged again and get the sectionIndex repopulated.
When you Short your List with different way ,you have a two option to load again .
after filled those new collection for adapter
1) you can make a notify this adapter .
2) you can fill set adapter again .
If by SectionIndexer which remains displayed you mean the section overlay you can achieve this by calling setFastScrollEnabled(false) before to switch to your other listadapter which does not implements SectionIndexer.

ListView's contents scrambled on scroll

So I am having a problem with the different pieces of that make up my ListView. I put them into an ArrayList and use a custom ArrayAdapter to hook up to the ListView, which I have done before so I don't believe there is a problem there. Initially the list seems to have the pieces in the correct order, but then I will scroll down the list and the contents will then load in incorrect order. I then scroll back up and everything is jumbled. Has anyone run into this before?
Thanks
-Jake
Yes your problem is related to the fact that List reuses the views for each row. So say your list can see 5 items, but your ListAdapter has 15 things in it. Android will create 5 + 1 instances of your row view instead of 15. One for each row in the list + 1 for when half of the top and bottom can be seen. When a row is moved out of the visible area the List will recycle that view instance for another row instead of creating a new one. If you don't properly reset all of the user interface components every time you'll get artifacts from other rows showing up. You must make sure that every time you bind your data from the objects in your array list to the view you set every field every time.
For a better description of this see
http://www.youtube.com/watch?v=N6YdwzAvwOA&feature=related

Categories

Resources