I am trying to get all holders from an recycler view in android.
The problem is that with my code i can only get only the holders from the visible elements(recyclerView.getChildAt(i)).
How can i get the elements that are recycled?
EDIT
Since i see that the question wasn't very clear, here is what i'm trying to do.
So i have a quiz, and i used a recyclerView for the questions. For every question, i have another recyclerView, in which i have the possible answers like a single selection.
So, at the end of the test, i need to get the answers from every question not just the ones visible.
I did something and i stored every questionHolder in a list but now i think that the usage of recyclerView is wrong here and doesn't provide any advantage.
The whole point of the ViewHolders is that they are recycled. I.e. when an item scrolls offscreen the same holder may be used for an item that is appearing on the other end.
Items that are recycled are, well, recycled. So you can't get to them.
This seems like an xy-problem. You may have to rethink what you are trying to do.
Related
My task is to develop a list of different type of questions, a survey. It could include types like Integer-Answer-Question, Long-Text-Answer-Question, and so on.
Why is it needed to be a list? Because for the people using the app is way better to scrolldown answering each question rather than swiping to right, or doing another movement.
So I was face to face with the dilemma of using a ListView or a RecyclerView. My research gave the final outcome of using a recyclerView and having a viewHolder for the different types of questions that I have.
The struggle came when I realized that there is a type of question that has dependency related to it; how so? if you select one option then you have to "show" some questions, and if you deselected this option then you have to "hide" it again.
The thing is that I need to know the reference of each question to their viewHolder in order to "show" o "hide" each of them, but if the recycler is recycling viewHolders then it could create a mess on my logic.
My punctual questions are: Am I using the correct component with the RecyclerView?, is there any way to access a viewHolder with a unique reference, like and id or something?.
if you need me to show some code, I'd do it happily.
Valuable information:
if you are interest in how notifyDataSetChanged() works you can access to this link for further and detail information.
Minas mina's approach was the correct one!
If I understand correctly, you need to hide some types of questions when the user selects an option.
Your understanding of what the view holders are supposed to do is not quite right. The view holders cache a bunch of views that you later use in onBindViewHolder() to fill-in data from your model objects.
The actual model objects should be in your adapter. In your case, something like
List<Question> questions
In onBindViewHolder(), you fill-in the fields of the View holder with the data from a Question object.
As for your question, what you can do is to set a flag in your recyclerView adapter, e.g. hideQuestionsOfTypeA to true and then call notifyDatasetChanged() on the adapter.
When binding objects, check if that flag is true and if yes, set the visibility to GONE to the views that need to be hidden.
I've got a RecyclerView which contains items, obviously. It uses the DefaultAnimator for all its animations.
When deleting an item, the deletion is animated, but not as it should be. The issue is that it seems like the size of the list is reduced by one first, then the clicked item is deleted and afterwards all items below are moved upwards by one. Take a look at this short video to see what I'm talking about.
The code used for the removal of a item is the following:
MainActivity.events.events.remove(listItems.keyAt(0));
notifyItemRemoved(listItems.keyAt(0));
Where MainActivity.events.events contains the data for the items and listItems.keyAt(0) contains the currently selected item.
What I've tried yet (none of this worked):
Made sure there's no other call which interrupts the animation (like notifyDataSetChanged()).
Implemented the above code directly into a onClickListener for the items inside the adapter.
Implemented the data directly into the adapter instead of a different class.
Replaced the position with getAdapterPosition() or a fixed value (i.e. 0)
Used notifyItemRangeRemoved() after notifItemRemoved().
Hint: I've got the animation to work previously, but as of today it doesn't work anymore.
EDIT:
If I remove the actual removal command (i.e. MainActivity.events.events.remove(listItems.keyAt(0));) from the code snippet given above, the animation is played correctly, but the element then isn't actually removed, so this doesn't solve the problem at all.
In my app i have a ListView with an ArrayAdapter. Every Item contains a picture, which takes a bit of time to render.
Now i want to add items dynamicly at the end of the List. The problem is, that wehenever add() is called my List blinks, because notifyDataSetChanged() is called and my pictures take a few milliseconds to render. I tried to avoid this by calling setNotifyOnChange(false). I solved the blinking with that, but unfortunately it is only updating the "length" of my list irregularly.
Is there some way to update the "length" of my listview, without updating the views which are shown?
I would agree that the UI thread should be avoided, especially for lists, and especially when using images for each list item.
Perhaps you need to find a more robust list adapter that is geared towards images? See this question for some helpful ideas/hints at how to improve your own list.
Also, the AndroidQuery (AQuery) library may be useful when fetching images for use in the arrayadapter: Image Loading via AQuery. It takes care of the burden of image caching as well, which I have found to be quite useful.
Good afternoon,
I have a list view that show a list of items...well not all of them but they are all there. Rather than let the user scroll up / down the requirement asks for and up / down buttons. I have everything handled quite well EXCEPT how to advance the ListView. Say I'm looking at item 3 in the list. The user hits next...I want to ListView to advance to item 4. I am keeping track internally of which page they are on for incrementing / decrementing. I was expecting to find something like this but no dice.
ListView.MoveNext();
or
ListView.Move(int);
Per Brayden's suggestion I tried the accepted solution here: Maintain/Save/Restore scroll position when returning to a ListView and it did not APPEAR to scroll the list....i.e. it stayed on the first list item. I also tried setSelection.
Here is my code:
public void btn_NextClick(View vw_Current)
{
//increment page count 1
i_PageTracker ++;
//advance to next record
//int x = lstvw_LiftData.getFirstVisiblePosition();
View v = lstvw_LiftData.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
lstvw_LiftData.setSelectionFromTop(i_PageTracker, top);
//lstvw_LiftData.setSelection(i_PageTracker);
}
Based upon Vladimir's success and my lack thereof I wanted to provide some additional info that I thought irrelevant but....
I've extended the SimpleAedapter and override the getView. I also have a DataBinder to populate TextViews with certain data from the data object.
Interestingly when I set a breakpoint in the getView of the DataAdapter and the setViewValue of the binder at load we hit them as appropriate. However when the next button is clicked we do not hit them which I would expect if the list was advancing to the next position....hmmmm I wonder....I have another Idea....be right back.
I figured it out....but I don't know what to do about it. See not knowing what I am doing I shot myself. I ONLY want to see one item in the list at a time and I don't want the user to be able to scroll. Well what I did to accomplish that was to override getCount in the DataAdapter and return a 1. This SEEMED to be the answer as only one item displayed cool! But then overriding getCount also means there is only one item to display so we never advance...there's nothing to advance to.
So what I want to know is this. How do I keep the user from being able to scroll and force them to use the navigation button. Do I handle the scroll event and return null?
I figured it out....but I don't know what to do about it. See not knowing what I am doing I shot myself. I ONLY want to see one item in the list at a time and I don't want the user to be able to scroll. Well what I did to accomplish that was to override getCount in the DataAdapter and return a 1. This SEEMED to be the answer as only one item displayed cool! But then overriding getCount also means there is only one item to display so we never advance...there's nothing to advance to.
So what I want to know is this. How do I keep the user from being able to scroll and force them to use the navigation button. Do I handle the scroll event and return null?
I'm working on an android application and I have run into a decision that I can't decide on one way or another. I was hoping someone could shed some light on the common practices and any theory to back them.
Here's the issue:
I want to have a list of items with images and text like table...
Country -.-.-.-.-.-.- Pop -.- SqrMi
[img] US -.-.-.-.-.-.- xxx -.-.- xxxxx
Now the debate I'm having is whether or not to use a listview to display the data or instead nest a layout that is scrollable and just display the data that way.
Why would I even consider a nested layout? Flexibility. I can design the dividers, possibly throw in a couple graphs above/below the list. Vary the height of each of the list items (like what if I want to show a graph in one list item and no graph in the next), etc.
I'm not sure if I'm breaking the generally accepted methods here. Can anyone shed some light on this?
The only major problem you will have when using nested layouts is memory consumption. ListView reuses its children so it doesn't create more children then it can display at a single moment. This description is a little simplified but I hope it shows the purpose of the ListView. Also ListView implements its own fast scrolling so it doesn't have to measure all its children to determine its size. And ListViews use adapters to populate themselves with data. It's a nice and convenient way to obtain data.
On the other hand if you create a ScrollView with a lot of views inside it'll be slow, difficult to populate with data and it'll require a lot of memory to create all of the child views even if you don't ever see some of them.
And about flexibility of the ListView. You can store different types of view in a single ListView and you'll be able to vary the height of each of this views.
All the things you have described for your "nested layout" is achievable with ListView. Just use different types of rows, use headers/footers in adapter.
And as already Pixie said, ListView is much more memory efficient and faster.