2013-08-17 59 views
0

我想定製用於掩蓋要顯示的實際圖像的圖像大小。在UIL(通用圖像加載程序)配置中,我們可以將.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


更新從代碼通用 - 圖像 - 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; 
    } 
} 
+1

如果您正在下載圖片,並從你的服務器與圖像有關的數據,那麼你可以保持在服務器中圖像的高度和寬度,第一拉來自服務器的所有圖像的高度和寬度信息,並根據您擁有的高度和寬度信息創建圖像視圖。 – Suru

+0

hhhm。不知道我能否做到這一點。圖像也可以自動調整到設備屏幕,例如,如果屏幕很小,圖像也會根據設備屏幕進行調整,以便它們也可以適合。所以在這種情況下,我需要將圖像的大小「顯示」並將其用於臨時圖像。 – rahstame

+0

選中此[回答](http://stackoverflow.com/a/18372834/2405196)。 – Mihir

回答

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; 
    } 
+0

我寧願選擇在顯示佔位符之前獲取圖像的大小,但我的問題是,我正在使用Universal-Image-Loader庫來處理顯示,所以我不知道如何處理獲取大小。我添加了來自.jar庫的代碼。 – rahstame

+0

很簡單。現在我將提供一些代碼來向您展示如何獲取尺寸。 –

+0

'url'不工作sir coz它是一個字符串。我爲我的進度添加了一個更新,而'showStubImage'只接受'int' – rahstame

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)方法,在DisplayImageOptions類imageView.setImageBitmap(sizedBitmap);

  3. 替換這一行imageView.setImageResource(options.getImageForEmptyUri());showStubImage(int stubImageRes),改變paramater作爲位圖,並做在該類必要的修改。

  4. 照顧所有需要改變的地方,這個特點在不同的地方反映出來。

更改位圖的大小:

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

除了上面的答案,我還會建議一件事情。根據您的要求,您將需要每次創建縮放位圖。因此,我建議您緩存原始位圖,而不是每次都抓取它。然後在該位置上進行縮放緩存的位圖只要你需要。 –

+0

@MehulJoisar偉大的一點! – rahstame