I'm having an issue with checkboxes on a listview, checking items, and listing just those checked items. This is my first android app, and without knowing what all is needed here in the way of code to help figure it out, I have recreated the problem in a bare-bones app that demonstrates what is going on. I suspect it is in the getView() method, but I'm not really sure.
Problem One: When more items are in the list than are visible, checking items at the top of the list also checks items that are not visible.
Problem Two: In the onOptionsItemSelected method there are two ways I've tried to get just the checked items. One is currently commented out, but they both fail in different ways. There are comments above each method that expalins what goes wrong.
Related
First of all, I have looked at similar questions (for example, this one: Android RecyclerView ItemTouchHelper revert swipe and restore view holder). This already helped a great deal, until I - more or less, accidentally - noticed my current (and hopefully, final) issue with this screen of mine.
Let's start with the setup:
I have a fragment with a RecyclerView filled with some CardView items (it's a little fancier, but that's what is important right now). I also created an ItemTouchHelper with the implementation of SimpleCallback (nothing in onMove()) to make swiping the items (right) possible. For the record: I am using API 27 right now.
So far, so good.
What I want to achieve:
I want to be able to swipe the items to be notified through the onSwiped() method of my SimpleCallback implementation. Also, I do NOT want the items to disappear, be removed, or otherwise taken out of my list of items in the RecyclerView. I just want to swipe them and have them return to their original position afterward (and yes, I know that it is sort of assumed that swiped items get removed). I am using the notifyItemChanged() method of my adapter in the onSwiped() method (also tried using notifyDataSetChanged()).
The problem:
Funnily enough, that works (mostly thanks to the aforementioned question) - until I hit that "app switch" button (don't know if there's actually one official name for it) and send the app to the background. Once I put it in the foreground again and start swiping, the items will not (visually) return. They are still on the list, and if I scroll or click the "app switch" button again, they will be displayed properly again (but won't return on swiping). Same if I navigate back one screen and come back to the list.
That makes me think something happens when I send the app to the background and recover it. Something different than navigating to that screen (in which case everything works as intended) - which I thought would more or less produce the same results. Any ideas what I might be overlooking here?
After some testing, I finally found the source of the issue:
I had both the RecyclerView and its Adapter initialised through onStart() of the Fragment and not onViewCreated(). After changing that, I got the proper results I wanted.
Lesson learned: Set your RecyclerView's Adapter as early as possible, unless you want to deal with sometimes strange issues.
I think I've read all the answers to all of the similar questions, and none of them seem to be fixing my problem,they're only workaround. I have recycler view with pictures taken by camera and they only update on scroll.
Using a smoothScrollToPosition() is workaround and I want to know the cause of this issue and fix it.
It's really weird because when a open my fragment and have a couple of images in the recycler view which I added earlier, deleting elements works perfect, but when I add new image from camera intent even the notification for deleting stops working, I have to do a scroll to refresh items in the adapter.
This is the part where I set the data:
viewModel.photos.observe(viewLifecycleOwner, Observer {
list->adapter.data = list
}).
Of course data is set in OnUiThread :
I checked with the debugger-- elements in list are updated.
Does anyone know the cause of this issue?
You have to tell recyclerView.adapter what exactly changed by calling notifyItemChanged. There are also other methods for inserted items, moved items, deleted items, etc. You can look at the full documentation here:
There is also another way by implementing a DiffUtil. You can research about it more. But the difference is that by using DiffUtil, you won't have to manually call those notify methods yourself.
Also, the old/unoptimized/unrecomenended way to do this is to simply call notifyDataSetChanged().
P.S. I highly think you found the somewhat the same answer while searching online and might have thought it as simply "a work around". I'm here to tell you that this is how its supposed to be handled.
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
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.
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.