Have you tried *not* caching the component views in your ViewHolder
object - instead looking them up whenever you get a redraw request?
You may find that the list is re-using objects, and your image issue
is simply an artifact of that.

Doug

On Jun 26, 10:56 pm, Peter <[email protected]> wrote:
> > There's not a default number of views created for an adapter. A list
> > creates as many views as it needs to fill the screen. Views get reused
> > only when you start scrolling or when the adapter send a
> > notifyDatasetChanged(). You say you have a thread updating the data,
> > what is exactly that thread doing? Please show code.
>
> Here is some code. Perhaps it will help.
>
> ********** the worker thread ***************
> --------------------------------------
>
>         class IconLoaderThread extends Thread {
>                 List<ObjectToShow> appList;
>                 void loadAllResources(List<ObjectToShow> appList) {
>                         this.appList = appList;
>                         start();
>                 }
>
>                 public void run() {
>                         int maxSize;
>
>                         for (int i = 0; i < maxSize; i++) {
>                                 ObjectToShow appInfo = appList.get(i);
> // network access occurs here
>                                 Bitmap icon = appQuery.lookupAppIcon(appInfo);
>                                 Message msg = 
> handler.obtainMessage(MSG_REFRESH_APP_ICON);
>                                 Bundle data = new Bundle();
>                                 data.putString("s3ObjectKey", 
> appInfo.getS3ObjectKey());
>                                 msg.obj = icon;
>                                 msg.setData(data);
>                                 handler.sendMessage(msg);
>                         }
>                         Message doneMsg = 
> handler.obtainMessage(MSG_ICONS_DONE);
>                         handler.sendMessage(doneMsg);
>                 }
>         }
>
> ********** the handler ***************
> --------------------------------------
>
>         private Handler handler = new Handler() {
>                 public void handleMessage(Message msg) {
>                         ObjectToShow appInfo;
>                         switch (msg.what) {
>                         case MSG_INIT_APP_LIST:
>                                 initProgressBar();
>                                 handler.sendEmptyMessage(MSG_NEXT_LOAD_STEP);
>                                 break;
>                         case MSG_REFRESH_APP_ICON:
>                                 Bitmap icon = (Bitmap)msg.obj;
>                                 String s3ObjectKey = 
> msg.getData().getString("s3ObjectKey");
>                                 if(icon == null || s3ObjectKey == null) {
>                                         Log.w(TAG, "Error loading icon");
>                                 } else {
>                                         
> efficientAdapter.updateAppInfoIcon(s3ObjectKey, icon);
>                                 }
>                                 break;
>                         case MSG_REFRESH_APP_METADATA:
>                                 appInfo = (ObjectToShow)msg.obj;
>                                 if(appInfo == null) {
>                                         Log.w(TAG, "Error loading icon");
>                                 } else {
>                                         
> efficientAdapter.updateAppInfoMetadata(appInfo);
>                                 }
>                                 break;
>                         case MSG_METADATA_DONE:
>                                 metadataLoaded = true;
>                                 handler.sendEmptyMessage(MSG_NEXT_LOAD_STEP);
>                                 break;
>                         case MSG_ICONS_DONE:
>                                 iconsLoaded = true;
>                                 handler.sendEmptyMessage(MSG_NEXT_LOAD_STEP);
>                                 break;
>                         case MSG_NEXT_LOAD_STEP:
>                                 if (metadataLoaded && iconsLoaded) {
>                                         doneLoadingMetadata();
>                                 }
>                                 else if (metadataLoaded || iconsLoaded) {
>                                         if (firstRun) {
>                                                 // Set the adapter here.
>                                                 firstRun = false;
>                                                 
> appListView.setAdapter(efficientAdapter);
>                                                 dismissLoadingMessage();
>                                         }
>                                         initIconThread();
>                                 }
>                                 else {
>                                         initMetadataThread();
>                                 }
>                                 break;
>                         default:
>                                 break;
>                         }
>                 }
>         };
>
> ********** the adapter ***************
> --------------------------------------
>
>         class EfficientAdapter extends BaseAdapter {
>                 private List<ObjectToShow> appLocalList;
>                 // IndexedObjectToShow just adds the int positions associated 
> with
> the item in the ListView
>                 private Map<String, IndexedObjectToShow> appLocalMap;
>                 private Map<String, Bitmap> iconMap = 
> Collections.synchronizedMap
> (new HashMap<String, Bitmap>());
>                 AppInfoComparator appInfoComparator = new AppInfoComparator();
>
>                 public void initList(List<ObjectToShow> appList) {
>                         if (appList != null) {
>                                 appLocalList = 
> Collections.synchronizedList(appList);
>
>                                 Collections.sort(appLocalList, 
> appInfoComparator);
>
>                                 appLocalMap = new TreeMap<String, 
> IndexedObjectToShow>();
>                                 Iterator<ObjectToShow> iter = 
> appLocalList.iterator();
>                                 int i = 0;
>                                 while (iter.hasNext()) {
>                                         ObjectToShow thisInfo = iter.next();
>                                         
> appLocalMap.put(thisInfo.getS3ObjectKey(), new IndexedObjectToShow
> (i, thisInfo));
>                                         i++;
>                                 }
>                                 appLocalMap = 
> Collections.synchronizedMap(appLocalMap);
>                         }
>                 }
>
>                 public long getItemId(int position) {
>                         int maxSize = appLocalList.size();
>                         if( (position < 0) || (position >= maxSize)) {
>                                 Log.w(TAG, "Position out of bounds in List 
> Adapter");
>                                 return -1;
>                         }
>                         return 
> appLocalMap.get(appLocalList.get(position).getS3ObjectKey
> ()).index;
>                 }
>
>                 public EfficientAdapter(Context c, List<ObjectToShow> 
> appList) {
>                         if (appList != null) {
>                                 // Just refresh the list
>                                 appLocalList = appList;
>
>                                 Collections.sort(appLocalList, 
> appInfoComparator);
>
>                                 appLocalMap = new TreeMap<String, 
> IndexedObjectToShow>();
>                                 Iterator<ObjectToShow> iter = 
> appLocalList.iterator();
>                                 int i = 0;
>                                 while (iter.hasNext()) {
>                                         ObjectToShow thisInfo = iter.next();
>                                         
> appLocalMap.put(thisInfo.getS3ObjectKey(), new IndexedObjectToShow
> (i, thisInfo));
>                                         i++;
>                                 }
>                         }
>                 }
>
>                 public int getCount() {
>                         return appLocalList.size();
>                 }
>
>                 public List<ObjectToShow> getList() {
>                         return this.appLocalList;
>                 }
>
>                 public boolean updateAppInfoIcon(String s3ObjectKey, Bitmap 
> icon) {
>                         if((s3ObjectKey == null) || (icon == null)) {
>                                 Log.w(TAG, "Null info when refreshing icon in 
> List Adapter");
>                                 return false;
>                         }
>                         IndexedObjectToShow aInfo = 
> appLocalMap.get(s3ObjectKey);
>                         if (aInfo != null) {
>                                 iconMap.put(aInfo.getS3ObjectKey(), icon);
>                                 notifyDataSetChanged();
>                                 return true;
>                         }
>                         return false;
>                 }
>
>                 public boolean updateAppInfoMetadata(ObjectToShow appInfo) {
>                         if((appInfo == null) || (appInfo.getS3ObjectKey() == 
> null)) {
>                                 Log.w(TAG, "Null info when refreshing 
> metadata in List Adapter");
>                                 return false;
>                         }
>                         IndexedObjectToShow aInfo = 
> appLocalMap.get(appInfo.getS3ObjectKey
> ());
>                         if (aInfo != null) {
>                                 aInfo.setMetadata(appInfo.getMetadata());
>                                 appLocalMap.put(aInfo.getS3ObjectKey(), 
> aInfo);
>                                 notifyDataSetChanged();
>                                 return true;
>                         }
>                         return false;
>                 }
>
>                 public Object getItem(int position) {
>                         return 
> appLocalMap.get(appLocalList.get(position).getS3ObjectKey
> ());
>                 }
>
>                 /*
>                  * This method returns the index of the package position in 
> the
> application list
>                  */
>                 public int getIndex(String pkgName) {
>                         if(pkgName == null) {
>                                 Log.w(TAG, "Getting index of null package in 
> List Adapter");
>                         }
>                         int maxSize = appLocalList.size();
>                         ObjectToShow appInfo;
>                         for(int i = 0; i < maxSize; i++) {
>                                 appInfo = appLocalList.get(i);
>                                 
> if(appInfo.getS3ObjectKey().equalsIgnoreCase(pkgName)) {
>                                         return i;
>                                 }
>                         }
>                         return -1;
>                 }
>
>                 public ObjectToShow getApplicationInfo(int position) {
>                         int maxSize = appLocalList.size();
>                         if( (position < 0) || (position >= maxSize)) {
>                                 Log.w(TAG, "Out of bounds");
>                                 return null;
>                         }
>                         return appLocalList.get(position);
>                 }
>
>                 public View getView(int position, View convertView, ViewGroup
> parent)
>                 {
>                         if (position >= appList.size()) {
>                                 return null;
>                         }
>                         ViewHolder holder;
>                         if (convertView == null) {
>                                 convertView = 
> mInflater.inflate(R.layout.app_list_item, null);
>                                 // Creates a ViewHolder and store references 
> to the two children
>                                 views
>                                 // we want to bind data to.
>                                 holder = new ViewHolder();
>                                 holder.appName = (TextView) 
> convertView.findViewById
>                                 (R.id.app_list_item_name);
>                                 holder.appIcon = (ImageView) 
> convertView.findViewById
>                                 (R.id.app_list_item_icon);
>                                 convertView.setTag(holder);
>                         } else {
>                                 holder = (ViewHolder) convertView.getTag();
>                         }
>                         ObjectToShow objectToShow = appList.get(position);
>                         ObjectToShow objectToShowWithMetadata = appMap.get
>                         (objectToShow.getKey());
>                         if(objectToShow != null) {
>                                 if(objectToShowWithMetadata.getName() != 
> null) {
>                                         
> holder.appName.setText(objectToShowWithMetadata.getName());
>                                 }
>                                 if(iconMap.get(objectToShow.getKey()) != 
> null) {
>                                         
> holder.appIcon.setImageBitmap(iconMap.get(objectToShow.getKey
>                                                         ()));
>                                 }
>                         } else {
>                                 holder.appName.setText(defaultText);
>                                 holder.appIcon.setImageDrawable(defaultIcon);
>                         }
>                         return convertView;
>                 }
>         }
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to