Aalok Sharma Aalok Sharma - 2 months ago 10
Android Question

how to maintain scroll position of listview when it updates

I have read plenty of examples ,but if i wish to maintain my scroll position after a listview is updated from json ,then can i do that without using an async task 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 ??

Answer

It is easier to mantain scroll position by calling notifydatasetchanged() only. The problem there is that you are creating a new adapter everytime the data gets updated... you should do something like this:

if(listView.getAdapter()==null)
   listView.setAdapter(myAdapter);
else{
   myAdapter.updateData(myNewData); //update your adapter's data
   myAdapter.notifyDatasetChanged();
}

This way, your listview will mantain the scrolling position.

In case you want to scroll to a new position, use:

list.smoothScrollToPosition(int position);