Android listview notifyDataSetChanged() jumpes to bottom - android

every time when I call notifyDataSetChanged() on my adapter the listview displayes the last item in the adapter array.
Is there any possible way to scroll the listview to the top off screen, since the setSelection(n) method within the post runnable is noticable, because the listview jumps to the bottom and then to the top. This movement can be seen on the screen unfortunately.
Thanks in advance.

When you call notifyDataSetChanged(), you're telling the ListView to refresh its contents, and it will actually try not to scroll if possible. It knows what it's currently scrolled to based on the items' positions and ids that it has obtained from the adapter. Your issue may be that your adapter is giving out inconsistent ids from getItemId that are confusing the ListView, causing it to scroll unnecessarily. Can you explain a little more about what your code is doing at the time you call notifyDataSetChanged()? Are you adding or removing items in the adapter at the same time?

I think this is what you need:
lv.setSelection(0);

Related

How to remember item "physical" position in recyclerView?

I have a dialog with RecyclerView of IDs in it. While I was choosing an id it changes its background. I did it by replacing adapter where I am putting newly selected position. And in my adapter item layout was chosen by its position where if equals to selected, it has another layout.
So after resetting a new adapter to recycler it losses current scroll position. I tried to use scrscrollToPosition, but it still not perfect, due to the situation that scrolled position is always on a beginning of RecyclerView.
So as I understand the problem I need to remember reference or some other scrolling data for setting it on the new adapter.
So If someone knew relevant RecyclerView methods or good practice for this problem, it would be nice =)
I don't think that here I need some code, cause it more practice question, but if someone need it I would add it.
Update: Meantime I found this method for getting offset of RecyclerView but still looking how to use this data in new adapter.
int offset = recyclerViewDialog.computeHorizontalScrollOffset();

Prevent RecyclerView to change position when loading additional items

I have a RecyclerView with setStackFromEnd(true) representing a chat list. And I want to load older messages when the list is scrolled to the top. I managed to do this using onScrollListener.
But when I add items to the adapter with messages.addAll(0, aListWithNewMessages) (messages is data set for adapter) and call notifyDataSetChanged(), new list items (as expected) appear before the existing ones and shift them down (not the experience a user wants), and I want to add them silently so a user shouldn't see it.
So my guess for how to tackle this issue is to scroll list to somehow previously saved position.
I understand that this is not a bug or an unexpected behavior, so please help to sort it out.
Thanks
Try being more specific. Instead of calling notifyDataSetChanged() use notifyItemRangeInserted or similar RecyclerView methods. That will allow RecyclerView to know what to do and will provide much better UX.

Footer as a one of the item on the ListView.

I'm trying to achieve the effect of the footer for ListView but without using the addFooterView method of the ListView. My intention is to treat the last visible item of the list as a pinned footer. In my view I can achieve this by detecting the last visible item on the list and dynamically change it's layout. I did some research and I think I must extend the BaseAdapter class providing two types of items. One for ordinary item on the list indicating that adapter should inflate the item with ordinary layout. And the second one indicating that adapter should inflate the current item with layout of footer. I think i must override the onScroll method to detect the last visible item. And here are my questions. Should i call the getView method from the onScrollmethod ? Is it the proper way to implement such effect? Is it possible at all? I would be grateful for any suggestions.
Thank in advance.
And here are my questions.
Should i call the getView method from the onScrollmethod ?
no, you should never directly call getView(). Only classes that extend AbsListView call getView
Is it the proper way to implement such effect?
No. The proper way of doing it is calling addFooterView to your ListView object.
Is it possible at all? I would be grateful for any suggestions.
No, it's not possible. Using scroll listeners you will never be able to find out when the AbsListView is requesting the "last view". That's because ListView does not guarantee the order it queries for Views. That's specially true when you 1st set the adapter or call notifyDataSetChanged which causes the ListView to get the views in several points to be able to layout and measure stuff it needs.
The suggestion is to use the addFooterView method, that's the correct way of doing, that's why it's there.

Should i use notifyDataSetChanged or update ListView items individually?

I've got a question about the performance of a ListView. My application uses a ListView with approximately 20 items and i was wondering what should i do if the data of one item has changed. Should i call notifyDataSetChanged() on the adapter and cause a redraw of the whole list or should i take care only of the item to refresh itself?
What is the cost of notifyDataSetChanged()? Can i use this without hesitation? An ListView item of mine has about 3-4 TextViews and an ImageView.
Any suggestions?
notifyDatasetChanged refreshes the whole list each time its called so it is better if you call that after you have all of your data that you want so you are not doing unnecessary work
mMyListView.invalidate();
mMyListView.invalidateViews();

Is there any difference between `ListView.invalidateViews()` and 'Adapter.notifyDataSetChanged()'?

Is there any difference between ListView.invalidateViews() and Adapter.notifyDataSetChanged()?
Well yes, there is.
ListView.invalidateViews() is used to tell the ListView to invalidate all its child item views (redraw them).
Note that there not need to be an equal number of views than items. That's because a ListView recycles its item views and moves them around the screen in a smart way while you scroll.
Adapter.notifyDataSetChanged() on the other hand, is to tell the observer of the adapter that the contents of what is being adapted have changed. Notifying the dataset changed will cause the listview to invoke your adapters methods again to adjust scrollbars, regenerate item views, etc...
Most of the time you would want to use notifyDataSetChanged instead of invalidateViews, but it certainly depends on what you are trying to accomplish.

Categories

Resources