为自定义全屏适配器设置占位符

时间:2013-12-21 10:49:45

标签: android performance bitmap

我正在使用全屏图库,我正在开发自定义适配器。 我想首先在应用程序启动时显示所有视图的占位符图像,并滚动视图(图像)从文件路径加载位图。

我正在使用Loading bitmaps efficiantly教程加载位图。

我的问题是,placeHolder图像只显示在应用中,并且不会加载其他图片。

我试图在我的AsyncTask类中的不同位置设置mPlaceHolder位图,例如doInBackground和onPostExecute,但它并没有帮助我。

我错过了一些事情吗?

这是我的适配器代码:

public View getView(int position, View convertView, ViewGroup parent) { 
    ImageView imageView;

    if (convertView == null) {
        imageView = new ImageView(mContext);
        imageView.setAdjustViewBounds(true);
        imageView.setPadding(20, 0, 20, 0);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    } else {
        imageView = (ImageView) convertView;
    }

    try {
        loadBitmap(imagePaths.get(position), imageView);
    } catch (Exception e) {
        // TODO: handle exception
    }

    //Bitmap bitmap =decodeFiles(imagePaths.get(position),width,height);
    /*
    try{
        image = decodeFile(new File(imagePaths.get(position)),screenMaxSize);
    }
    catch (Exception e) {
        // TODO: handle exception
        Log.i("erroe", imagePaths.get(position));
    }
    */


    //imageView.setImageBitmap(bitmap);

    //imageView.setLayoutParams(new GridView.LayoutParams(90, 70));

   return imageView;


}

public void loadBitmap(String filePath, ImageView imageView) {
    if (cancelPotentialWork(filePath, imageView)) {
        final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
        final Bitmap *mPlaceHolderBitmap* = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.gallery_icon);

        final AsyncDrawable asyncDrawable =
                new AsyncDrawable(mContext.getResources(), mPlaceHolderBitmap, task);
        imageView.setImageDrawable(asyncDrawable);
        task.execute(filePath);
    }
}


public Bitmap decodeFiles(String pathName, int reqWidth,int reqHeight){

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(pathName, options);

    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
   /*
   int scale = 1;
   if (o.outHeight > screenMaxSize || o.outWidth > screenMaxSize) {
       scale = (int)Math.pow(2, (int) Math.round(Math.log(screenMaxSize / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
   }
   */

   //Decode with inSampleSize
    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(pathName, options);
}

private int calculateInSampleSize(Options options, int reqWidth, int reqHeight) {
    // TODO Auto-generated method stub
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}


public static boolean cancelPotentialWork(String filePath, ImageView imageView) {
    final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

    if (bitmapWorkerTask != null) {
        final String bitmapData = bitmapWorkerTask.data;
        if (bitmapData != filePath) {
            // Cancel previous task
            bitmapWorkerTask.cancel(true);
        } else {
            // The same work is already in progress
            return false;
        }
    }
    // No task associated with the ImageView, or an existing task was cancelled
    return true;
}

private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
       if (imageView != null) {
           final Drawable drawable = imageView.getDrawable();
           if (drawable instanceof AsyncDrawable) {
               final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
               return asyncDrawable.getBitmapWorkerTask();
           }
        }
        return null;
}

class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private String data = "";

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(String... params) {
        data = params[0];
        return decodeFiles(data, width, height);
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            final BitmapWorkerTask bitmapWorkerTask =
                    getBitmapWorkerTask(imageView);
            if (this == bitmapWorkerTask && imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }

    }
}

static class AsyncDrawable extends BitmapDrawable {
    private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

    public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
        super(res, bitmap);
        bitmapWorkerTaskReference =
            new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
    }

    public BitmapWorkerTask getBitmapWorkerTask() {
        return bitmapWorkerTaskReference.get();
    }
}

2 个答案:

答案 0 :(得分:0)

这可能是因为您没有在执行后通知您的适配器:

protected void onPostExecute(Bitmap bitmap) {
    if (isCancelled()) {
        bitmap = null;
    }

    if (imageViewReference != null && bitmap != null) {
        final ImageView imageView = imageViewReference.get();
        final BitmapWorkerTask bitmapWorkerTask =
                getBitmapWorkerTask(imageView);
        if (this == bitmapWorkerTask && imageView != null) {
            imageView.setImageBitmap(bitmap);
        }
    }
    <YoutAdapterName>.this.notifyDataSetChanged()//<<---do it here

}

答案 1 :(得分:-1)

使mPlaceHolderBitmap成为适配器级变量并在调用loadBitmap()之前进行设置。