检测要显示的图像大小,并通过延迟加载图像使用它

时间:2013-08-17 09:21:37

标签: java android bitmap universal-image-loader

我想自定义用于掩盖要显示的真实图像的图像大小。在UIL(Universal-Image-Loader)配置中,我们可以将.showStubImage(R.drawable.temp_drawable)作为显示选项。

我的问题是,我正在实施一个像pinterest一样的观点。当我从图像滚动时,图像中存在这种不稳定的位置,因为它们仍然被下载并被临时绘制覆盖。例如,临时可绘制的是45 X 45,然后要显示的图像是100 x 50.当显示真实图像时,在滚动时图像具有这种位移效果,因为临时图像被真实图像替换。有没有什么方法可以检测到真实的图像高度和宽度,当它仍然被下载时,使用宽度和高度,临时图像可以使用它暂时显示图像大小?

    options = new DisplayImageOptions.Builder()
    .showStubImage(R.drawable.ic_stub)
    .showImageForEmptyUri(R.drawable.ic_empty)
    .showImageOnFail(R.drawable.ic_error)
    .cacheInMemory(true)
    .cacheOnDisc(true)

  imageLoader.displayImage(imageUrls[position], hold.image, options);

enter image description here


来自Universal-Image-Loader.jar的

更新 代码

public void displayImage(String uri, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener) {
    checkConfiguration();
    if (imageView == null) {
        throw new IllegalArgumentException(ERROR_WRONG_ARGUMENTS);
    }
    if (listener == null) {
        listener = emptyListener;
    }
    if (options == null) {
        options = configuration.defaultDisplayImageOptions;
    }

    if (TextUtils.isEmpty(uri)) {
        engine.cancelDisplayTaskFor(imageView);
        listener.onLoadingStarted(uri, imageView);
        if (options.shouldShowImageForEmptyUri()) {
            imageView.setImageResource(options.getImageForEmptyUri());
        } else {
            imageView.setImageDrawable(null);
        }
        listener.onLoadingComplete(uri, imageView, null);
        return;
    }

    ImageSize targetSize = ImageSizeUtils.defineTargetSizeForView(imageView, configuration.maxImageWidthForMemoryCache, configuration.maxImageHeightForMemoryCache);
    String memoryCacheKey = MemoryCacheUtil.generateKey(uri, targetSize);
    engine.prepareDisplayTaskFor(imageView, memoryCacheKey);

    listener.onLoadingStarted(uri, imageView);
    Bitmap bmp = configuration.memoryCache.get(memoryCacheKey);
    if (bmp != null && !bmp.isRecycled()) {
        if (configuration.writeLogs) L.d(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey);

        if (options.shouldPostProcess()) {
            ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageView, targetSize, memoryCacheKey, options, listener, engine.getLockForUri(uri));
            ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo, options.getHandler());
            engine.submit(displayTask);
        } else {
            options.getDisplayer().display(bmp, imageView, LoadedFrom.MEMORY_CACHE);
            listener.onLoadingComplete(uri, imageView, bmp);
        }
    } else {
        if (options.shouldShowStubImage()) {
            imageView.setImageResource(options.getStubImage());
        } else {
            if (options.isResetViewBeforeLoading()) {
                imageView.setImageDrawable(null);
            }
        }

        ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageView, targetSize, memoryCacheKey, options, listener, engine.getLockForUri(uri));
        LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo, options.getHandler());
        engine.submit(displayTask);
    }
}

我喜欢`.showStubImage(getImageDimension())'

其他

new DownloadFilesTask().execute(imageUrls[position]);

private class DownloadFilesTask extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub


        URL uri = null;
        try {
            uri = new URL(params[0].toString());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

         InputStream in=null;
      try
        {
          //URL oracle = new URL(url);
        URLConnection urlConnection = uri.openConnection();
        in = new BufferedInputStream(urlConnection.getInputStream());
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(in , null, options);
        //return options;
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      finally
        {
        if(in!=null)
             IoUtils.closeSilently(in);

        }
        return null;
    }
}

2 个答案:

答案 0 :(得分:2)

这与Android无关。这是关于你的应用程序的设计。

如果是您的服务器,您应该决定图像的大小以及如何管理它们,并相应地放置正确的占位符。

如果它不是您的服务器,您无法以任何方式联系服务器而无法知道图像的大小,因此您必须设置图像适合的静态大小,或获取图像的大小在显示占位符之前。

使用inJustDecodeBounds解码时,使用与其他文件相同的方式获取服务器文件的图像分辨率。

编辑:这是一个如何从互联网上获取位图大小的示例代码:

public static BitmapFactory.Options getBitmapOptions(final String url) 
  {
  InputStream in=null;
  try
    {
    URLConnection urlConnection = url.openConnection();
    in = new BufferedInputStream(urlConnection.getInputStream());
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(in , null, options);
    return options;
    }
  finally
    {
    if(in!=null)
      IOUtils.closeQuietly(in);        
    }
  return null;
  }

答案 1 :(得分:2)

通常,您可以根据下面的库提供资源ID。

options = new DisplayImageOptions.Builder().showStubImage(R.drawable.stubImage)....

如果你需要放置动态变化大小的存根图像,你需要调整源代码,使你的选项应该接受大小的位图而不是int。为此,我刚刚查看了源代码。以下是步骤:

  1. 您需要做的就是将其包含在库项目中,而不是在libs文件夹中添加.jar。

  2. 在ImageLoader类中,然后在public void displayImage(String uri, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener)方法中,替换此行imageView.setImageResource(options.getImageForEmptyUri());imageView.setImageBitmap(sizedBitmap);

  3. 在DisplayImageOptions类的showStubImage(int stubImageRes)中,将参数更改为位图,并在该类中进行必要的更改。

  4. 在不同部分反映此功能的地方,处理需要更改的所有事项。

  5. 更改位图的大小:

     Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
                                   R.drawable.stub_image);
      bitmap = Bitmap.createScaledBitmap(stub, width, height, false);