Retaining position in ListView after calling notifyDataSetChanged
Could this be what you want?
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
// notify dataset changed or re-assign adapter here
// restore the position of listview
mList.setSelectionFromTop(index, top);
EDIT 28/09/2017:
The API has changed quite a bit since 2015. It is similar, but now it would be:
// save index and top position
int index = mList.FirstVisiblePosition; //This changed
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.Top; //this changed
// notify dataset changed or re-assign adapter here
// restore the position of listview
mList.setSelectionFromTop(index, top);
notifyDataSetChanged() makes the list refresh and scroll jumps back to the top
Such behaviour is not normal. Without seeing your code I can suggest following:
1) You are not calling notifyDataSetChanged()
from the UI thread. The correct way:
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});
2) You accidentally or not are making a call to adapter.notifyDataSetInvalidated();
3) In your adapter you override the adapter.notifyDataSetChanged();
method and added instruction to go to top
4) If you're using a list to populate adapter - you supply new list every time, so adapter settings are refreshed. You should always supply the same list. However you can change it as much as you want. If you're resetting the list use list.clear
instead of list = new ArrayList();
Here is an example of my adapter:
public class Adapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
public ImageLoader imageLoader;
public MediaItemAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.item_composer, null);
}
TextView title = (TextView) vi.findViewById(R.id.item_title); // title
TextView price = (TextView) vi.findViewById(R.id.price);
return vi;
}
}
Call for adapter:
List myList = new ArrayList<HashMap<String, String>>();
Adapter ma = new Adapter(this, myList);
myList can be empty before adapter initialization.
Then do some operation with my list:
myList.add(someElement);
ma.notifyDataSetChanged();
if you need delete all items:
myList.clear();
ma.notifyDataSetChanged();
Such implementation is pretty endless, I saw more then 15 thousand elements without any problems.
How to fix notifyDataSetChanged/ListView problems in dynamic Adapter wrapper Android
The main problem with the approach presented above was that the data set was being changed directly from within code executed by the superclasses. By populating the headings in getView() I was changing the data in what could be the middle of an operation or an "unsafe" state in the superclasses. This is why all touch interaction broke when onNotifyDataSetChanged was called during a fling scroll. The data needs to be added from an external source, not from within the adapter methods.
That can be done by using a Handler or AsyncTask to add the headings to the adapter and call its notifyDataSetChanged. These will be run on a UI thread and will not interfere with the superclass state. Thanks to CommonsWare's EndlessAdapter example for introducing the concept of an AsyncTask to add data to a list.
The onTouchEvent() and layoutChildren() hacks were no longer needed after making that change.
how to maintain scroll position of listview when it updates
It is easier to maintain scroll position by calling notifydatasetchanged() only. The problem there is that you are creating a new adapter every time the data gets updated... you should do something like this:
if(listView.getAdapter()==null)
listView.setAdapter(myAdapter);
else{
myAdapter.updateData(myNewData); //update adapter's data
myAdapter.notifyDataSetChanged(); //notifies any View reflecting data to refresh
}
This way, your listview will mantain the scrolling position.
In case you want to scroll to a new position, use:
list.smoothScrollToPosition(int position);
How to remain at a scroll position in RecyclerView after adding items at its first index and call notifydatasetchange
There are two options:
Use the more sophisticated versions of
notify
List newData = createLineItems(dataArrayList);
mCurrentFragment.items.addAll(0, newData);
notifyItemRangeInserted(0, newData.size());Use stable IDs. On your adapter override
public long getItemId (int position)
to make it return MEANINGFUL values and callsetHasStableIds(true);
on it.
Android ViewPager with ListView can not remember the last position when called notifyDatasetchanged
You can use this logic... before call dataSetChanged store this listview state in Parcelable
varaiable and after dataSetChanged time for restore the listview from a value which you have strored in a parcelable variable
like this ..
Parcelable scrollPos=listview.onSaveInstanceState();
// call your pagerAdapter.notifyDataSetChanged
if(scrollPos != null)
{
listview.onRestoreInstanceState(scrollPos);
}
there is another way i found it from here
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
// notify dataset changed or re-assign adapter here
// restore the position of listview
mList.setSelectionFromTop(index, top);
Related Topics
Sending a Notification from a Service in Android
Problem to Load Flv Video in Webview
Android Setting with Textview for Hebrew Text
Error:Execution Failed For Task ':App:Transformclasseswithjarmergingfordebug'
Simple Example for Intent and Bundle
A Way to Get Unlock Event in Android
How to Dynamically Remove Items from Listview on a Button Click
In Androidx.Fragment.App.Fragment,Setuservisiblehint()Is Deprecated,And Not Executed,Why
Action_Sendto for Sending an Email
Programmatic Views How to Set Unique Id'S
Multi Selection Spinner in Android Without Alertdialog