【问题标题】:setting place holder for a custom full screen adapter为自定义全屏适配器设置占位符
【发布时间】:2014-01-10 04:12:26
【问题描述】:

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

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

我的问题是那个 placeHolder 图像只是显示在应用程序中,它不会加载其他图像。

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

我有什么事情要做吗?

这是我的适配器代码:

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();
    }
}

【问题讨论】:

    标签: android performance bitmap


    【解决方案1】:

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

    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
    
    }
    

    【讨论】:

    • Tnx 回答,但我只看到我所有图像的第一个初始位图:-(
    【解决方案2】:

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

    【讨论】:

    • 我是否真的因为有人不喜欢我的(正确)答案的语法而被否决了?这是我费心给出的第一个答案,而在这种接待下,它很可能是我的最后一个答案。欢迎新用户的好方法!
    猜你喜欢
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多