0

我想自定义用于掩盖要显示的真实图像的图像大小。在 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);

在此处输入图像描述


从 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;
    }
}
4

2 回答 2

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. showStubImage(int stubImageRes)DisplayImageOptions 类中,将参数更改为 Bitmap 并在该类中进行必要的更改。

  4. 在此功能反映在不同部分的地方,请注意所有需要更改的内容。

更改位图的大小:

 Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
                               R.drawable.stub_image);
  bitmap = Bitmap.createScaledBitmap(stub, width, height, false);
于 2013-08-19T11:28:11.907 回答
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;
  }
于 2013-08-17T14:32:48.017 回答