Android - ListView images shuffled when scrolling -


i'm trying make listview dynamically loaded images, using asynctask download image , set listview. problem that, while scrolling down, images randomly changed.

public class getallcustomerlistviewadapter extends baseadapter {  private jsonarray dataarray; private activity activity;  private static layoutinflater inflater = null; private static final string baseurlforimage = "http://192.168.254.1/contact/images/";  public getallcustomerlistviewadapter(jsonarray jsonarray, activity a) {     this.dataarray = jsonarray;     this.activity = a;       inflater = (layoutinflater) this.activity.getsystemservice(context.layout_inflater_service); }  @override public int getcount() {     return this.dataarray.length(); }  @override public object getitem(int position) {     return position; }  @override public long getitemid(int position) {     return position; }  @override public view getview(int position, view convertview, viewgroup parent) {      // set convert view if null     final listcell cell;     if (convertview == null)     {         convertview = inflater.inflate(r.layout.get_all_customer_list_view_cell, null);         cell = new listcell();          cell.fullname = (textview) convertview.findviewbyid(r.id.customer_full_name);         cell.age = (textview) convertview.findviewbyid(r.id.customer_age);          cell.mobile = (imageview) convertview.findviewbyid(r.id.customer_mobile);          convertview.settag(cell);     }     else     {         cell = (listcell) convertview.gettag();     }      // change data of cell      try     {         jsonobject jsonobject = this.dataarray.getjsonobject(position);         cell.fullname.settext(jsonobject.getstring("firstname")+" "+jsonobject.getstring("lastname"));         cell.age.settext(" "+jsonobject.getint("age"));          string nameofimage = jsonobject.getstring("id");          string urlforimageinserver = "http://192.168.254.1/contact/getimage.php?id="+nameofimage;          new asynctask<string, void, bitmap>() {              @override             protected bitmap doinbackground(string... params) {                 string url = params[0];                 bitmap icon = null;                  try {                     inputstream in = new java.net.url(url).openstream();                     icon = bitmapfactory.decodestream(in);                 } catch (ioexception e) {                     // todo auto-generated catch block                     e.printstacktrace();                 }                  return icon;             }              protected void onpostexecute(bitmap result) {                 cell.mobile.setimagebitmap(result);                          }                          }.execute(urlforimageinserver);                   }     catch (jsonexception e)     {         e.printstacktrace();     }       return convertview; }    private  class  listcell {     private textview fullname;     private textview age;      private imageview mobile;  }     

}

i did (at 1am actually)- problem listview actively recycling views. therefore, gets old views still holds bitmaps.

the following need:

[note: check if bitmap cached earlier. if not, steps below]

  1. cache bitmap first before trying load it
  2. cache targeted imageview (and keep track of bitmap supposed go bitmap). also, empty out imageview in case still contains bitmap previous recycled item (imageview.setimagebitmap(null);)
  3. double check cached imageview has not been cached previous item already. if cached previously, somehow state bitmap being received should not loaded (i did storing imageview every spot, , once bitmap received, if row's imageview null again don't load in bitmap)
  4. load bitmap (as mentioned above) if still should- ie, if imageview wasn't recycled again. mentioned earlier

the solution albeit bit complicated works , smoothly if implemented correctly. if you'd example, feel free check 1 out in action here in current project.

edit requested example:

here not-so-pseudo pseudocode. main part still need implement lazy loading system (which whole other topic). once again, feel free visit project linked above , @ "imageloadernocache" networkutil.

public class getallcustomerlistviewadapter extends baseadapter {      private jsonarray dataarray;     private activity activity;      private static layoutinflater inflater = null;     private static final string baseurlforimage = "http://192.168.254.1/contact/images/";      // list caches bitmaps target imageviews, in order of rows     private arraylist<rowviewdata> rowviewdatalist;      public getallcustomerlistviewadapter(jsonarray jsonarray, activity a)     {         this.dataarray = jsonarray;         this.activity = a;           inflater = (layoutinflater) this.activity.getsystemservice(context.layout_inflater_service);          // initialize list         rowviewdatalist = new arraylist<rowviewdata>(dataarray.length());          // more of preference, add in every item rowviewdatalist         for(int = 0; < dataarray.length(); ++i) {             // create new, empty rowviewdata instance , put list             rowviewdata rowdata = new rowviewdata();             rowviewdatalist.add(rowdata);         }     }      @override     public int getcount() {         return this.dataarray.length();     }      @override     public object getitem(int position) {         return position;     }      @override     public long getitemid(int position) {         return position;     }      @override     public view getview(int position, view convertview, viewgroup parent) {          // set convert view if null         final listcell cell;         if (convertview == null)         {             convertview = inflater.inflate(r.layout.get_all_customer_list_view_cell, null);             cell = new listcell();              cell.fullname = (textview) convertview.findviewbyid(r.id.customer_full_name);             cell.age = (textview) convertview.findviewbyid(r.id.customer_age);              cell.mobile = (imageview) convertview.findviewbyid(r.id.customer_mobile);              convertview.settag(cell);         }         else         {             cell = (listcell) convertview.gettag();         }          // change data of cell          try         {             jsonobject jsonobject = this.dataarray.getjsonobject(position);             cell.fullname.settext(jsonobject.getstring("firstname")+" "+jsonobject.getstring("lastname"));             cell.age.settext(" "+jsonobject.getint("age"));               // rowviewdata position             rowviewdata currowviewdata = rowviewdatalist.get(position);              // if bitmap cached, use             if(currowviewdata.bitmap != null) {                 cell.mobile.setimagebitmap(currowviewdata.bitmap);             }             // otherwise, gotta real work             else {                 // first, set cell's imageview's bitmap null                 //      [in case recycled view bitmap]                 cell.mobile.setimagebitmap(null);                  // then, start caching system                 string nameofimage = jsonobject.getstring("id");                 string urlforimageinserver = "http://192.168.254.1/contact/getimage.php?id="+nameofimage;                  // create system load images lazily , receive bitmaps                 // @ imageloadernocache example. feel free reuse                 /**                  * = adapter should implement interface. below corresponding method                  * url = image source url                  * position = position bitmap belongs to. returned along bitmap reference                  */                 lazyimageloader.getbitmap(this, url, position);                  // cache/target imageview later                 currowviewdata.targetimageview = cell.mobile;                  // double check imageview not being targeted elsewhere                 //      ie, 1 of recycling fixes [else, 2 bitmaps load @ once, etc]                 //  also, more efficient                 for(int = 0; < rowviewdatalist.size(); ++i) {                     // if current position, skip logic round                     if(i == position) continue;                      // rowviewdata round                         // yeah... should've used "cell" instead of row you...                     rowviewdata checkrowdata = rowviewdatalist.get(i);                      // if targeted imageview same, null-ify                     if(checkrowdata.targetimageview == currowviewdata.targetimageview) {                         // old 1 should null bitmap should not load                         //      current recycled item                         checkrowdata.targetimageview = null;                          // personally, knew there 1 copy @ time                         //      tried save time breaking out here. feel free                         //          cautious , comment out break statement                         break;                     }                 }             }         }         catch (jsonexception e)         {             e.printstacktrace();         }           return convertview;     }      /**      * should called part of interface lazyimageloader      * @param bitmap - lazily loaded bitmap requested earlier      * @param position - row/cell position bitmap requested      */     public void getbitmapforposition(bitmap bitmap, int position) {         // rowviewdata instance row/position         rowviewdata currowdata = rowviewdatalist.get(position);          // cache bitmap         currowdata.bitmap = bitmap;          // check if bitmap should loaded still         if(currowdata.targetimageview != null) {             currowdata.targetimageview.setimagebitmap(bitmap);              // not sure if strictly necessary, practice make cached view null             currowdata.targetimageview = null;         }     }      private  class  listcell     {         private textview fullname;         private textview age;          private imageview mobile;      }      // holds data lazily loading image bitmap     private class rowviewdata {         public imageview targetimageview;         public bitmap bitmap;     } } 

Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -