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 AsyncTask
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 ??
This example demonstrates how do I dynamically update a ListView in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.
ListView itself is scrollable.
ListView uses Adapter classes which add the content from data source (such as string array, array, database etc) to ListView.
ScrollView is used to put different or same child views or layouts and the all can be scrolled. ListView is used to put same child view or layout as multiple items. All these items are also scrollable. Simply ScrollView is for both homogeneous and heterogeneous collection.
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);
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With