I've got a ListView with a method (public ArrayAdapter<String> populateListView(){}) to update the Adapter. Every 500ms I call lv.setAdapter(populateListView();. This works, but if I'm scrolling down the ListView, when the method is called it resets my view and automatically scrolls me to the top. So if I'm 80% down my ListView, when the method is called I'm reset to 0%.
How do I continually populate my ListView without resetting the scroll position?
I've already tried calling lv.getScrollY(); before setting the adapter and then lv.setScrollY(); but this doesn't help. I've also tried calling lv.scrollTo(0, scrollY); but this doesn't help.
How do I stop resetting the scroll position when updating the adapter?
Try updating the items in the adapter and call adapter.notifyDataSetChanged() instead of creating a new adapter.
Example:
adapter.replaceItems(yourNewListWithData);
adapter.notifyDataSetChanged();
You have to implement the replaceItems method yourselves.
public void replaceItems(List<? extends E> newItems) {
entries.clear();
entries.addAll(newItems);
}
Related
I have a RecyclerView that contains a ListView, and every time the back end database changes (via the update() method in the ContentProvider), the ContentProvider calls getContext().getContentResolver().notifyChange(uri, null), which makes the RecyclerView scroll to top.
I understand that if we are updating the view in the adapter, we can just call notifyDatasetChanged() and then smooth scroll to the current position in the activity. But since I've already been only calling notifyDatasetChanged() in the Adapter, and this problem is caused the notifyChange() in the ContentProvider, does anyone have an idea how to solve it?
Also I have a LoaderManager in my Activity, and no ContentObserver is needed.
I have a ListView and a Custom Adapter. The Custom Adapter implements an AsyncTask to load some images from a server. Everything works fine when the activity is created. However, the ListView has a Load Button to load more rows, each row contains an image. The new data (images) are added properly to the ListView when de Load Button is pressed. However, the ListView is not refreshed despite notifyDataSetChanged is called. I have to move the scoll to refresh the ListView and the new data are displayed. The problem is that the new images are loaded in the AsyncTask inside the Adapter and when notifyDataSetChanged is called in the MainActivity, the AsyncTask is not finished yet. So, my question is: Is there any way to refresh the ListView once the AsyncTask is finished? Calling notifyDataSetChanged inside the Adapter or another alternative?
In your asynctask onPostExecute it should be something like this:
#Override
protected void onPostExecute(String result) {
((MainActivity) getActivity).notifyDataChanged();
}
Depending on how your code is organized you will call notifyDataChanged() in some way similar to this one.
So, my question is: Is there any way to refresh the ListView once the AsyncTask is finished?
Yes you can do that :
Pass the ListView to the AsyncTask,
override the onPostExecute() method,
call notifyDataChanged in the onPostExecute() method.
I have come across many such questions similar to mine.
But i have a slightly different question and i could not find any answer yet.
I have written a CustomAdapter for my ListView.
I wanted to try something new by implementing animations for my ListView items.
Hence i have implemented bottom-to-up animation similar to Google+ card animations.
Here is the code of the animation.
Animation animation = AnimationUtils.loadAnimation(getContext(), (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
animation.setDuration(400);
rowView.startAnimation(animation);
lastPosition = position;
I have written this code in the getView() of my CustomAdapter.
In my application i need to call the getView() method twice.
Everything works fine till here.
Now the problem i face because of calling getView() more than once is, the card animation too occurs twice one after the other as my list is loaded twice.
How can i make my animation to perform only once? even while it is in the getView() method?
Is there any way to do this?
Add one more flag in GSSListAdapter class constructor to check is getView method is called first time or second time:
public boolean isShowAnimation=false;
GSSListAdapter(...,...,boolean isShowAnimation){
...
this.isShowAnimation=isShowAnimation;
}
now use isShowAnimation for checking perform Animation or not in getView method of Adapter.
I have a listfragment, whose listview is loaded using a cursorloader from the contacts provider. An onScrollListener is also registered.
Requirement : The scroll listener is triggered whenever the user does a scroll through the UI. But i need to trigger it automatically when the listview is loaded for the first time as well.
Problem : I have tried using smoothScrollToPosition(0) in onActivityCreated() to trigger the scroll, but it does not scroll no matter what position i provide as parameter. Based on some other posts on SO, I have tried using setSelection() instead, which does work, but does not trigger the scroll listener. I have tried the post method as well as below, but it makes no difference :
v.post(new Runnable() {
#Override
public void run() {
v.smoothScrollToPosition(0);
}
});
Any other way to trigger a scroll automatically?
I've got a custom Adapter for a ListView setup and working ok. On a button click something is changed in the underlying data, so a notifyDataSetChanged is required to refresh the ListView. Fine. But I also want the ListView to scroll to the line where the change occurred. For this I call smoothScrollToPosition immediately after the notifyDataSetChanged. And that is not working.
If I do not call notifyDataSetChanged then the scroll works, so the notify blocks the scroll. I'm probably having a fight with events being processed in the future. Can anybody give me a pointer on what is going wrong?
Use the post() method to wait for the list to finish updating after you call notifyDataSetChanged():
adapter.notifyDataSetChanged();
list.post( new Runnable() {
#Override
public void run() {
//call smooth scroll
}
});
I've tried the dmon's example code and I see it not always working.
Actually I've found another approach to perform scrolling:
adapter.notifyDataSetChanged();
channelsListView.setSelection(scrollPos); // it works without smoothScrollToPositionFromTop(..) or smoothScrollToPosition() methods call.
I found the main idea to use above method after this answer reading:
https://stackoverflow.com/a/20997828/2133585