Frage

I am using a SimpleCursorTreeAdapter to display data in database. I am using loaders to manage all the cursors. Everything works fine. But there are some images in each of the child views. This causes a noticeable stutter when scrolling. So I want to use an asynctask to decode the images in background. Something like (pseudocode):

@Override                                                                                                        
protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {                   
        super.bindChildView(view, context, cursor, isLastChild);                                                 
        String imgFile = cursor.getString(MyDatabaseHelper.FILE_INDEX);                                          
        new asyncLoadImage().execute(imgFile);                                                                   
}                                                                                                                

private class asyncLoadImage extends AsyncTask<String, Void, Bitmap> {                                           

        @Override                                                                                                
        protected Bitmap doInBackground(String... arg0) {                                                        
                String imgFile = arg0[0];                                                                        
                return Utils.getBitMap(imgFile);//psuedocode                                                     
        }                                                                                                        

        @Override                                                                                                
        protected void onPostExecute(Bitmap bm) {                                                                
                ImageView imageView = new ImageView(mCtx);                                                       
                imageView.setTag(mID);                                                                           
                imageView.setImageBitmap(bm);                                                                    
                //ok got the imageview. where do I append it ??                                                  
        }                                                                                                        
}      

By the time the imageview is ready in onPostExecute() function, the view provided in bindChildView might have been recycled and pointing to some different child element. How do I determine where to append the imageview?

War es hilfreich?

Lösung

First, don't append. You need the ImageView there anyway. Have the ImageView use a placeholder image, that you replace with the final image when it is ready.

Second, consider using an existing library that knows about Adapter recycling, such as Picasso. Admittedly, I don't know if Picasso has support for ExpandableListAdapter, as I rarely use ExpandableListView.

If you determine that there is no suitable library, you'll need some logic in your getChildView() and/or getGroupView() methods that can deal with recycling and your background work. One fairly simple approach is to tuck the URL of the image needed by the ImageView in the tag of the ImageView via setTag(). Your onPostExecute() can then compare the URL it just downloaded with the URL from the ImageView tag, and if they do not match, do not update the ImageView. This means that you will download some images unnecessarily, so a more sophisticated approach will arrange to cancel the AsyncTask that is downloading the image. And I am sure that there are other approaches as well.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top