how to maintain scroll position of listview when it updates
Solution 1
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);
Solution 2
In case for some reason you don't want to call notifyDataSetChanged(), the you can maintain the position by using setSelectionFromTop()
Before updating the adaptor:
lastViewedPosition = listView.getFirstVisiblePosition();
//get offset of first visible view
View v = listView.getChildAt(0);
topOffset = (v == null) ? 0 : v.getTop();
After updating the adaptor:
listView.setSelectionFromTop(lastViewedPosition, topOffset);
Solution 3
list.smoothScrollToPosition(int position); //my favorite :)
It may also help you to scroll nice'n'smooth to a particular item
Solution 4
listview.setSelection( i );
this will help you to set particular row at top
Solution 5
For overall picture:
In your API response callback, call this function(example) below:
MyAdapter mAdapter;
ArrayList<Users> mUsers;
private void updateListView(ArrayList<Users> users) {
mUsers.addAll(users);
if(mAdapter == null) {
mAdapter = new MyAdapter(getContext(), mUsers);
mListView.setAdapter(mAdapter);
}
mAdapter.notifyDataSetChanged(); // Add this one
}
Related videos on Youtube
Aalok Sharma
Updated on April 23, 2020Comments
-
Aalok Sharma about 4 years
I have read plenty of examples ,but if I wish to maintain my scroll position after a
ListView
is updated fromJSON
,then can I do that without using anAsyncTask
instance ???the code for my list is
String wrd; //ArrayList<HashMap<String,String>> mylist; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent i2=getIntent(); wrd=i2.getStringExtra("entrd"); Log.v("keyis",wrd); final Handler handler = new Handler(); Runnable runable = new Runnable() { @Override public void run() { //call the function LoadData(); //also call the same runnable handler.postDelayed(this, 40000); } }; handler.postDelayed(runable, 10); }public void LoadData(){ JSONObject j2=JSONfunctions.getJSONfromURL("/webservice_search.php?keyword="+wrd+"&format=json"); ArrayList<HashMap<String,String>> mylist = new ArrayList<HashMap<String,String>>(); try{JSONArray jray=j2.getJSONArray("listings"); for(int i=0;i<jray.length();i++){ Log.v("state","json data being read"); JSONObject j3= jray.getJSONObject(i); String first=j3.getString("listing"); Log.v("sublist", first); JSONObject j4=j3.getJSONObject("listing"); String sec=j4.getString("links"); int maxLength = (sec.length() < 30)?sec.length():27; sec.substring(0, maxLength); String cutsec=sec.substring(0,maxLength); Log.v("links are",cutsec); String img=j4.getString("image_name"); Log.v("image name is ",img); //Uri dimg=Uri.parse("http://zeesms.info/android_app_images/Koala.jpg"); HashMap<String,String> map=new HashMap<String,String>(); map.put("Id",String.valueOf(i)); map.put(Li_nk,cutsec); map.put(Image_name,j4.getString("image_name")); map.put(KEY_THUMB_URL,"http://zeesms.info/android_app_images/"+img); mylist.add(map); } } catch(JSONException e){ Log.e("loG_tag","Error parsing"+e.toString()); } LazyAdapter adapter = new LazyAdapter(this,mylist); adapter.notifyDataSetChanged(); ListView list=(ListView)findViewById(R.id.lv1); list.setEmptyView(findViewById(R.id.empty)); list.setAdapter(adapter); list.setItemsCanFocus(false);
and my adapter is
public class LazyAdapter extends BaseAdapter { private Activity activity; private ArrayList<HashMap<String, String>> data; private static LayoutInflater inflater=null; public ImageLoader imageLoader; public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) { activity = a; data=d; inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); imageLoader=new ImageLoader(activity.getApplicationContext()); } @Override public int getCount() { // TODO Auto-generated method stub return data.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View vi=convertView; if(convertView==null) vi = inflater.inflate(R.layout.custom_row_view1, null); TextView title = (TextView)vi.findViewById(R.id.linkname); // merchnts name TextView artist = (TextView)vi.findViewById(R.id.imagename); // address //TextView duration = (TextView)vi.findViewById(R.id); // distance ImageView thumb_image=(ImageView)vi.findViewById(R.id.mClogo); // logo HashMap<String, String> jsn = new HashMap<String, String>(); jsn = data.get(position); // Setting all values in listview title.setText(jsn.get(Second.Li_nk)); artist.setText(jsn.get(Second.Image_name)); //duration.setText(song.get(CustomizedListView.KEY_DURATION)); imageLoader.DisplayImage(jsn.get(Second.KEY_THUMB_URL), thumb_image); return vi; }
and finally the class being used for json parsing is
public class JSONfunctions { public static JSONObject getJSONfromURL(String url){ InputStream is = null; String result = ""; JSONObject jArray = null; String str1="http://zeesms.info"+url; // ArrayList<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>(); Log.v("url result",url); //namevaluepairs.add(new BasicNameValuePair("location",str1)); //http post try{ HttpClient httpclient= new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI(str1)); HttpResponse response = httpclient.execute(request); is = response.getEntity().getContent(); if(is==null){ Log.v("url result","is null"); } else { Log.v("url result","is not null"); } /* BufferedReader buf = new BufferedReader(new InputStreamReader(is,"UTF-8")); StringBuilder sb = new StringBuilder(); String s; while(true ) { s = buf.readLine(); if(s==null || s.length()==0) break; sb.append(s); } buf.close(); is.close(); sb.toString(); */ // httppost.setEntity(new UrlEncodedFormEntity(namevaluepairs)); //HttpResponse response=httpclient.execute(httppost); //HttpEntity entity=response.getEntity(); //is=entity.getContent(); /* HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); is = entity.getContent(); */ }catch(Exception e){ Log.v("log_tag", "Error in http connection "+e.toString()); AlertDialog.Builder alert=new AlertDialog.Builder(null); alert.setMessage("Invalid Keyword").setPositiveButton("Ok", new OnClickListener(){ @Override public void onClick(DialogInterface arg0, int arg1) { // TODO Auto-generated method stub } }); } //convert response to string try{ Log.v("url result","getting result starts"); BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8); StringBuilder sb = new StringBuilder(); String line = null; Log.v("url result","getting result"); while ((line = reader.readLine()) != null) { Log.v("url result","getting result"); sb.append(line + "\n"); } is.close(); result=sb.toString(); Log.v("url result",result); }catch(Exception e){ Log.e("log_tag", "Error converting result "+e.toString()); } try{ jArray = new JSONObject(result); }catch(JSONException e){ Log.e("log_tag", "Error parsing data "+e.toString()); } return jArray; } }
along with this if the data is updated from the webpage, what would be the simplest way to show the updated item on top ??
-
Aalok Sharma about 12 yearsshould I add this after datasetnotify change ?? or in my oncreate??
-
waqaslam about 12 yearsat very last - when your list has items to scroll about
-
Aalok Sharma about 12 yearsJust a quick query,if I wish to reverse the order of my list here ,i.e if I want that the last item shows up first and so on,how do I do tht ?
-
waqaslam about 12 yearsEither reverse your ArrayList and call notifyDataSetChanged() on your adapter, or set setStackFromBottom(true) to your listview before setting adapter.
-
Aalok Sharma about 12 yearsHow do I reverse the array list? I've tried the setStackFromBottom(true),but it simply scrolls down to the last item
-
waqaslam about 12 yearsThen just reverse the items in your ArrayList and call notifyDataSetChanged() on adapter.
-
Aalok Sharma about 12 yearsNo I meant that without using the stackfrom bottom,what code must I write to reverse the array ??
-
waqaslam about 12 yearsyes, i'm not either talking about stackfrom bottom. Read this
-
Hugh Jeffner about 8 yearsCame to the same conclusion after finding this: stackoverflow.com/a/14719538/383761
-
Harsha over 7 yearsafter notifydatasetchanged new page loaded and display view from page one please help every new page loaded and moves to top
-
Sebastian Breit over 7 yearsYou are not using it right. If it moves to top, you are re-inserting all items into the list
-
Vikrant over 7 years@SebastianBreit Im new to this , but can you explain how to use myAdapter.updateData(myNewdata); ? What should be passed in myNewdata ? Elaborate please ?
-
Sebastian Breit over 7 years@Vikrant, normally that would be any kind of list of objects. (array/arraylist/vector). Inside of your adapter, you would have a reference to that list for showing it in your view. I strongly recommend you take a look at any android adapter tutorial
-
fida1989 almost 7 years@lenooh: Me too!
-
Sabri Meviş about 6 yearsExcellent! My list doesn't move anymore. It stays where its on remove and insert.
-
Buntu Linux almost 6 yearsbest answer, saved my day
-
Sakiboy almost 5 yearsThis actually addresses the problem. Thank you! Works great.