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 -~----------~----~----~----~------~----~------~--~---

