RecyclerView items reset when scrolling down - android

I'm using RecyclerView with expandable list items. The problem is that when I expand an item and scroll the items off-screen gets reset like this:
Is there any way to fix this and preserve the item's state?
Thanks in advance.

You need the object in your ListAdapter to store the expansion state. It may be that you need to create a new class that wraps the existing data and adds a boolean indicating if the row is expanded. Then, when you re-initialize the view as the list is scrolled, you can set the view to be expanded or collapsed according to the data in the adapter. The view itself can't hold this state for you because the view object is "recycled" to display a different record as the user scrolls.

Related

Expandable recycler view always collapse on updating adapter

I am using recycler view(https://github.com/thoughtbot/expandable-recycler-view) to display list of sections and subsections. It is working just fine. But when I am trying to update the list with live data and using :- recyclerView.adapter = adapter by creating adapter everytime when live data updates. But when data is updated, it collapses the each section regardless it was expanded already. I want to keep state of list as it was when updating it. Can someone tell me how to achieve this or any other way of updating the adapter that keep the state of list same(if it is expanded, remain expanded, collapsed, remain same). Thanks in advance.

Get ListView item position by uri / by the data it contains

I have a ListView which I populate using a custom CursorAdapter.
Now I want to manually update just one specific item in the ListView. I have the content URI of that item. Is it possible to use just this info to get the position of the item in the listView?
If I have the position I can do something like
View v = mListView.getChildAt(itemPosition - mListView.getFirstVisiblePosition());
to update the view. But how can I get itemPosition?
I know that I get the position in the onItemClickListener, but I need to update the view without it being clicked.
Any help guys?
ListView does not support updating a single position.
You must update the adapter with the new data (even if you change a single position) and the, invoke mAdapter.notifyDataSetChanged()
If you get the View by its position (via listView.getChildAt()) will work. However, if you scroll up and down the list, that view will display the old data again because the adapter is not aware of the change (and it is the adapter which update the view contect view getView()).
When you invoke notifyDataSetChanged(), you are telling to the adapter that your data set has new info and the ListView/Adapter will re-draw the visible items (it won't re-draw whole list at once.. only the visible items).
You may want to consider to change to RecyclerView in the future. The BaseAdapter used in a RecyclerView support actions such as add/remove/update a single position.

Nested RecyclerView scrolls to the first item on NotifyItemChanged

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.

How do I apply layout changes to one individual ListView item without the adapter recycling the layout to other items?

I have a custom adapter for a ListView. On getView(), I attach an onTouchListener to the convertView.
Upon touch of the item/convertView, I update the ViewHolder's RelativeLayout's LayoutParams to be shifted left and set a couple buttons revealed underneath the uppermost layout to clickable, as described on a few swipeable ListView guides.
Unfortunately, when I scroll down my ListView, other items also now have the layout slid to the side with the buttons set clickable underneath. I am not sure why a change to a single ViewHolder is being recycled to others, but I'm sure I'm just falling prey to a simple misunderstanding. Can anyone offer an explanation and solution? Thanks!
After recycling a view you should reset the view to its initial state and populate it with the new values.
You can use an simple Array of booleans for this. for example,
List has 5 items so initially array will be-
arr[false,false,false,false,false]
When you select any item then update arrays value at that items positions-
list item 1 selected - arr [true,false,false,false,false]
list item 3 selected - arr [true,false,true,false,false]
list item 5 selected - arr [true,false,true,false,true]
and check array's values in getView's method-
if(arr[position] == false)
{
// item not selected so do changes you want in non-selected items
}
else
{
// item selected so do changes you want in selected items
}

how to use view holder if custom listview row content are dynamic?

i have create custom list view using base adapter to dynamic row
content.row content are created programmatically (check box,text view) they are include in layout.
problem to scrolling time they are very slow because not use
view holder. how can i use view holder this type of custom list view?
any solution or suggestion?
following this list..
ViewHolder is use in a list view when same view is repeated. Say there are total 6 items visible at a time in your activity. Then using viewholder pattern 6+2=8 views will be inflated at a time. one extra at the top and one extra at the bottom to give smooth scrolling effect. Now suppose scroll up operation is performed, and item at 8th position is visible, item at 0th position will be recycled and appended at the end of the list as the 9th item. if the views are not same this recycling can not be performed. check https://www.youtube.com/watch?v=wDBM6wVEO70
For your problem you can assume there is 5 maximum value possible then you can create adapter view using 10 dynamic views inside and set visibility as required.
Another optionis use LinearLayout and add each row dynamically but this won't give much optimization.

Categories

Resources