studio programacion herramientas fundamentos con avanzado aplicaciones android json listview scroll autoscroll

android - programacion - cómo mantener la posición de desplazamiento de listview cuando se actualiza



manual de android en pdf (6)

He leído muchos ejemplos, pero si deseo mantener mi posición de desplazamiento después de actualizar un ListView desde JSON , ¿puedo hacerlo sin usar una instancia de AsyncTask ?

el código para mi lista es

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);

y mi adaptador es

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; }

y, finalmente, la clase que se utiliza para analizar JSON es

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; } }

junto con esto si los datos se actualizan desde la página web, ¿cuál sería la forma más sencilla de mostrar el elemento actualizado en la parte superior?


En caso de que, por alguna razón, no quiera llamar a NotifyDataSetChanged (), puede mantener la posición utilizando setSelectionFromTop ()

Antes de actualizar el adaptador:

lastViewedPosition = listView.getFirstVisiblePosition(); //get offset of first visible view View v = listView.getChildAt(0); topOffset = (v == null) ? 0 : v.getTop();

Después de actualizar el adaptador:

listView.setSelectionFromTop(lastViewedPosition, topOffset);


Es más fácil mantener la posición de desplazamiento llamando solo a notificationdatasetchanged (). El problema es que está creando un nuevo adaptador cada vez que se actualizan los datos ... debe hacer algo como esto:

if(listView.getAdapter()==null) listView.setAdapter(myAdapter); else{ myAdapter.updateData(myNewData); //update adapter''s data myAdapter.notifyDataSetChanged(); //notifies any View reflecting data to refresh }

De esta manera, su vista de lista mantendrá la posición de desplazamiento.

En caso de que quiera desplazarse a una nueva posición, use:

list.smoothScrollToPosition(int position);


Para el cuadro general:

En su devolución de llamada de respuesta de API, llame a esta función (ejemplo) a continuación:

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(); }


Si está utilizando un ArrayAdapter (o una subclase de él), el problema puede deberse a que el adaptador actualiza la lista cuando la limpia antes de agregar los nuevos elementos:

adapter.clear(); adapter.addAll(...);

Puede solucionarlo envolviendo el código que modifica el adaptador de esta manera:

adapter.setNotifyOnChange(false); // Disable calling notifyDatasetChanged() on modification adapter.clear(); adapter.addAll(...); // Notify the adapter about that data has changed. Note: it will re-enable notifyOnChange adapter.notifyDataSetChanged();


list.smoothScrollToPosition(int position); //my favorite :)

También puede ayudarlo a desplazarse por la suavidad a un elemento en particular.


listview.setSelection( i );

Esto te ayudará a establecer una fila particular en la parte superior.