er... On 6月30日, 下午10时40分, Streets Of Boston <flyingdutc...@gmail.com> wrote: > Your code in your getView implementation of the adapter looks good at > first sight. The structure of this method looks good. > > I think there are a few issues though. > > In your getView(...) method, you access the variable 'appList': > > if (position >= appList.size()) { > return null; > } > > and > > ObjectToShow objectToShow = appList.get > (position); > ObjectToShow objectToShowWithMetadata = > appMap.get > > The only place i can find a declared variable called 'appList' in your > example code is the one that is a private member of IconLoaderThread: > > class IconLoaderThread extends Thread { > List<ObjectToShow> appList; > ... > } > > In short, this 'appList' is accessed in two threads without any > synchronization or attempt to make it immutable. > > Also, the plain assignment here worries me: > public EfficientAdapter(Context c, List<ObjectToShow> > appList) { > if (appList != null) { > // Just refresh the list > --> appLocalList = appList; <--- > ... > } > ... > } > > because in the method 'initList' you do something similar, but you > assign a copy of appList to appLocalList. > > On Jun 30, 12:43 am, Peter <pkana...@gmail.com> wrote: > > > Doug, you were right. > > > If I inflate a new view each time instead of using the cached > > convertView, the images never show incorrectly. This is obviously less > > efficient, but it's right. I need to look more closely to see if I was > > abusing the ViewHolder pattern, but I don't see how I was. > > > This is what I'm doing now in convertView(): > > > public View getView(int position, View convertView, ViewGroup > > parent) > > { > > if (position >= appList.size()) { > > return null; > > } > > convertView = mInflater.inflate > > (R.layout.app_list_item, null); > > > ObjectToShow objectToShow = appList.get > > (position); > > ObjectToShow objectToShowWithMetadata = > > appMap.get > > (objectToShow.getKey()); > > if(objectToShow != null) { > > if(objectToShowWithMetadata.getName() ! > > = null) { > > ((TextView) > > convertView.findViewById(R.id.app_list_item_name)).setText > > (objectToShowWithMetadata.getName()); > > } > > if(iconMap.get(objectToShow.getKey()) ! > > = null) { > > ((ImageView) > > convertView.findViewByI(R.id.app_list_item_icon)).setImageBitmap > > (iconMap.get(objectToShow.getKey())); > > } > > } else { > > ((TextView)convertView.findViewById > > (R.id.app_list_item_name)).setText(defaultText); > > ((ImageView)convertView.findViewByI > > (R.id.app_list_item_icon)).setImageDrawable(defaultIcon); > > } > > return convertView; > > } > > > Any thoughts? > > > On Jun 27, 4:17 pm, Doug <dougforp...@gmail.com> wrote: > > > > 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 <pkana...@gmail.com> wrote: > > > > > > There's not adefaultnumberof 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(); > > ... > > 阅读更多 >>
--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---