android - BaseAdapter.notifyDataSetChanged inverts order of elements -
for navigation in android app using listview , create , set baseadapter in oncreate method of activity.
the baseadapter accesses arraylist retrieve elements (cache.getnavigation()):
public class navigationadapter extends baseadapter { context mcontext; public navigationadapter(context c) { mcontext = c; } @override public int getcount() { return cache.getnavigation() != null ? cache.getnavigation().size() : 0; } @override public object getitem(int position) { return cache.getnavigation() != null ? cache.getnavigation().get( position) : 0; } @override public long getitemid(int position) { return cache.getnavigation() != null ? cache.getnavigation().get( position).getid() : 0; } @override public view getview(int position, view convertview, viewgroup parent) { view v; if (convertview == null) { layoutinflater li = getlayoutinflater(); v = li.inflate(r.layout.list_nav_icon, null); textview tv = (textview) v.findviewbyid(r.id.list_nav_text); tv.settext(((templateinstancedto) getitem(position)) .getname()); imageview icon = (imageview) v .findviewbyid(r.id.list_nav_icon); byte[] binary = ((templateinstancedto) getitem(position)) .geticon(); bitmap bm = bitmapfactory.decodebytearray(binary, 0, binary.length); icon.setimagebitmap(bm); imageview arrow = (imageview) v .findviewbyid(r.id.list_nav_arrow); arrow.setimageresource(r.drawable.arrow); } else { v = convertview; } return v; } }
so navigation built on startup cache. meanwhile start asynctask retrieves navigation arraylist server , when has changed saves new navigation cache:
private class remotetask extends asynctask<long, integer, list<templateinstancedto>> { protected list<templateinstancedto> doinbackground(long... ids) { try { remotetemplateinstanceservice service = (remotetemplateinstanceservice) servicefactory .getservice(remotetemplateinstanceservice.class, getclassloader()); list<templateinstancedto> templates = service .findbyaccountid(ids[0]); return templates; } catch (exception e) { return null; } } protected void onpostexecute(list<templateinstancedto> result) { if (result != null && result.size() > 0) { cache.savenavigation(result); populatedata(); } else { toast text = toast.maketext(listnavigationactivity.this, "server communication failed.", 3); text.show(); } } }
when nothing more in populatedata()
, listview doesn´t update. when call ((baseadapter) listview.getadapter()).notifydatasetchanged()
view updated, order inverted. first item last , last first , on.
held needed! in advance.
the problem lies getview() function. through different calls of method, view objects cached, though not coupled position.
with proper logs, can see behavior as:
pos1: view1 pos2: view2 pos3: view3 pos3: view1 pos2: view2 pos1: view3
thats why list getting inverted. solution: on each call of getview, set values in value if object exists. i.e.:
public view getview(int position, view convertview, viewgroup parent) { view v; if (convertview == null) { layoutinflater li = getlayoutinflater(); v = li.inflate(r.layout.list_nav_icon, null); } else { v = convertview; } textview tv = (textview) v.findviewbyid(r.id.list_nav_text); tv.settext(((templateinstancedto) getitem(position)) .getname()); imageview icon = (imageview) v .findviewbyid(r.id.list_nav_icon); byte[] binary = ((templateinstancedto) getitem(position)) .geticon(); bitmap bm = bitmapfactory.decodebytearray(binary, 0, binary.length); icon.setimagebitmap(bm); imageview arrow = (imageview) v .findviewbyid(r.id.list_nav_arrow); arrow.setimageresource(r.drawable.arrow); return v; }
Comments
Post a Comment