2012-07-26 8 views
12

Ho un'applicazione per visualizzare le immagini dal server. ora sono pigro a caricare le mie immagini. quindi inizialmente visualizzerò una barra di avanzamento quando l'immagine finirà il caricamento rimuoverò la barra di avanzamento impostandola come attributo visibility su View.INVISIBLE e l'immagine appare. Questo è il file di layout che uso per le immaginiL'immagine di caricamento pigro con barra di avanzamento danneggia l'immagine quando l'immagine è visualizzata

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_gravity="center" > 

    <ImageView 
      android:id="@+id/imageView1" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:layout_gravity="center" 
      android:contentDescription="@string/app_name" 
      android:scaleType="centerInside" 
      android:src="@drawable/ic_launcher" /> 

    <RelativeLayout 
     android:id="@+id/loading_layout" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:background="@android:color/white" > 

     <ProgressBar 
      android:id="@+id/progressBar1" 
      style="?android:attr/progressBarStyleSmall" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_centerVertical="true" 
      android:background="@android:color/white" /> 
    </RelativeLayout> 

</FrameLayout> 

Il problema Quando la barra di avanzamento scompaiono l'immagine visualizzata sullo schermo, ma danneggiato. come questa immagine

quando aggiorno la lista le immagini caricate dalla directory della cache e quando vengono visualizzate sullo schermo vengono visualizzate correttamente senza alcun danno.

enter image description here

classe ImageLoader io uso dell'immagine carico pigro per

public class ImageLoader { 
    // @@ JUST FOR THIS PROJECT 
    BaseAdapter mAdapter; 
    // @@ 
    MemoryCache memoryCache = new MemoryCache(); 
    FileCache fileCache; 
    private Map<ImageView, String> imageViews = Collections 
      .synchronizedMap(new WeakHashMap<ImageView, String>()); 
    ExecutorService executorService; 

    boolean addRoundCournerAndStroke = false; 
    boolean scale = false; 

    boolean localfile = false; 
    int default_image; 

    public ImageLoader(Context context, boolean flag, boolean scale, 
      boolean localfile) { 
     fileCache = new FileCache(context); 
     this.addRoundCournerAndStroke = flag; 
     executorService = Executors.newFixedThreadPool(5); 
     this.scale = scale; 
     this.localfile = localfile; 

    } 

    public ImageLoader(Context context, boolean flag, boolean scale, 
      boolean localfile, int default_image_id) { 
     this(context, flag, scale, localfile); 
     this.default_image = default_image_id; 
    } 

    public ImageLoader(Context context, boolean flag, boolean scale, 
      boolean localfile, int default_image_id, BaseAdapter adapter) { 
     this(context, flag, scale, localfile); 
     this.default_image = default_image_id; 
     this.mAdapter = adapter; 
    } 

    public void DisplayImage(String url, ImageView imageView) { 
     imageViews.put(imageView, url); 
     Bitmap bitmap = memoryCache.get(url); 
     if (bitmap != null) { 
      changeProgressBarVisibilty(imageView, false); 
      imageView.setImageBitmap(bitmap); 
     } 

     else { 
      queuePhoto(url, imageView); 
      imageView.setImageResource(this.default_image); 
     } 
    } 

    private void queuePhoto(String url, ImageView imageView) { 
     PhotoToLoad p = new PhotoToLoad(url, imageView); 
     executorService.submit(new PhotosLoader(p)); 
    } 

    private Bitmap getBitmap(String url) { 
     File f = null; 
     if (localfile) 
      f = new File(url); 
     else 
      f = fileCache.getFile(url); 

     // Log.d("bytes", "decode"); 
     // from SD cache 
     Bitmap b = decodeFile(f); 
     if (b != null) 
      return b; 

     // from web 
     try { 
      Bitmap bitmap = null; 

      URL imageUrl = new URL(url); 
      HttpURLConnection conn = (HttpURLConnection) imageUrl 
        .openConnection(); 
      conn.setConnectTimeout(30000); 
      conn.setReadTimeout(30000); 
      conn.setInstanceFollowRedirects(true); 
      InputStream is = conn.getInputStream(); 
      OutputStream os = new FileOutputStream(f); 
      Utils.CopyStream(is, os); 
      os.close(); 

      bitmap = decodeFile(f); 
      // //Log.d("bytes", "decode"); 
      return bitmap; 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      return null; 
     } 
    } 

    private Bitmap decodeFileWithoutScaling(File f) { 
     try { 
      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize = 1; 
      //o2.inPurgeable = true; 
      if (this.localfile) 
       return BitmapFactory.decodeFile(f.getAbsolutePath(), o2); 
      else 
       return BitmapFactory.decodeStream(new FileInputStream(f), null, 
         o2); 
     } catch (FileNotFoundException e) { 
     } 
     return null; 
    } 

    private Bitmap decodeFile(File f) { 

     if (this.scale) { 
      return decodeFileWithScalling(f); 
     } else { 
      return decodeFileWithoutScaling(f); 
     } 
    } 

    // decodes image and scales it to reduce memory consumption 
    private Bitmap decodeFileWithScalling(File f) { 
     try { 
      // decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 

     // o.inPurgeable = true; 
      if (this.localfile) 
       BitmapFactory.decodeFile(f.getAbsolutePath(), o); 
      else 
       BitmapFactory.decodeStream(new FileInputStream(f), null, o); 

      // Find the correct scale value. It should be the power of 2. 
      final int REQUIRED_SIZE = 70; 
      int width_tmp = o.outWidth, height_tmp = o.outHeight; 
      // Log.d("width", width_tmp + ""); 
      // Log.d("height", height_tmp + ""); 
      int scale = 1; 
      while (true) { 
       if (width_tmp/2 < REQUIRED_SIZE 
         || height_tmp/2 < REQUIRED_SIZE) 
        break; 
       width_tmp /= 2; 
       height_tmp /= 2; 
       scale *= 2; 
      } 

      // decode with inSampleSize 
      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize = scale; 
     // o2.inPurgeable = true; 
      // Log.d("after shave width", o2.outWidth + ""); 
      // Log.d("after shave height", o2.outHeight + ""); 
      if (this.localfile) 
       return BitmapFactory.decodeFile(f.getAbsolutePath(), o2); 
      else 
       return BitmapFactory.decodeStream(new FileInputStream(f), null, 
         o2); 
     } catch (FileNotFoundException e) { 
     } 
     return null; 
    } 

    // Task for the queue 
    private class PhotoToLoad { 
     public String url; 
     public ImageView imageView; 

     public PhotoToLoad(String u, ImageView i) { 
      url = u; 
      imageView = i; 
     } 
    } 

    class PhotosLoader implements Runnable { 
     PhotoToLoad photoToLoad; 

     PhotosLoader(PhotoToLoad photoToLoad) { 
      this.photoToLoad = photoToLoad; 
     } 

     public void run() { 
      if (imageViewReused(photoToLoad)) { 
       return; 
      } 

      Bitmap bmp = getBitmap(photoToLoad.url); 

      // if (addRoundCournerAndStroke) { 
      // // bmp = ImageHelper.rotateAndFrame(bmp, 10); 
      // bmp = ImageHelper.getRoundedCornerBitmap(bmp, 10); 
      // } 

      memoryCache.put(photoToLoad.url, bmp); 
      if (imageViewReused(photoToLoad)) 
       return; 
      BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); 
      Activity a = (Activity) photoToLoad.imageView.getContext(); 
      a.runOnUiThread(bd); 
     } 
    } 

    boolean imageViewReused(PhotoToLoad photoToLoad) { 
     String tag = imageViews.get(photoToLoad.imageView); 
     if (tag == null || !tag.equals(photoToLoad.url)) 
      return true; 
     return false; 
    } 

    // Used to display bitmap in the UI thread 
    class BitmapDisplayer implements Runnable { 
     Bitmap bitmap; 
     PhotoToLoad photoToLoad; 

     public BitmapDisplayer(Bitmap b, PhotoToLoad p) { 
      bitmap = b; 
      photoToLoad = p; 
     } 

     public void run() { 
      if (imageViewReused(photoToLoad)) 
       return; 
      changeProgressBarVisibilty(photoToLoad.imageView, false); 
      if (bitmap != null) { 
       photoToLoad.imageView.setImageBitmap(bitmap); 


      } else { 
       photoToLoad.imageView 
         .setImageResource(ImageLoader.this.default_image); 

      } 
      if (mAdapter != null) { 
       mAdapter.notifyDataSetChanged(); 
      } 

     } 
    } 

    private void changeProgressBarVisibilty(ImageView image, boolean visible) { 
     ViewGroup layout = (ViewGroup) image.getParent(); 

     try { 
      View v = layout.findViewById(R.id.loading_layout); 
      v.setVisibility(visible ? View.VISIBLE : View.GONE); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 



    } 



    public void clearCache() { 
     memoryCache.clear(); 
     fileCache.clear(); 
    } 

} 
+2

Prova a utilizzare la libreria [Universal Image Loader] (https://github.com/nostra13/Android-Universal-Image-Loader) per il caricamento delle immagini. Forse non ha questo problema. – NOSTRA

+0

Invece di nascondere la barra di avanzamento, quando l'immagine viene caricata, rendere visibile l'immagine. Nascondilo prima di iniziare a caricare ... – Ronnie

risposta

5

tenta di utilizzare ProgressDialog invece di Progressbar. ProgressDialog può anche usare la barra di avanzamento. ProgressDialog non è un tipo XML. in modo da poter mostrare() o licenziare() metodo. Forse non ha questo problema. Penso che questo problema provenga da RelativeLayout. Se si utilizza ProgressBar Visiblity, RelativeLayout è ancora visibile (ma non ha sfondo). Anche RelativeLayout ha qualsiasi oggetto. Immagino che il layout vuoto ti abbia dato la corruzione. Utilizzando ProgressDialog è meglio ..

-1

penso che si può provare a impostare la visibilità come View.GONE, perché quando si imposta la View.INVISIBLE Vista detiene ancora il posto e, come Tae ha detto che può essere alcuni problemi con RelativeLayout.

Acclamazioni

3

Le mostra l'immagine danneggiati artefatti-JPEG danneggiati.

Il problema può sorgere dal metodo BitmapFactory.decodeStream. Non tutti i file JPEG sono ottimizzati per la decodifica immediata ("progressiva"), quindi è necessario che siano disponibili nel loro insieme prima di essere decodificati correttamente. Di solito, le immagini non progressive possono essere decodificate dall'alto verso il basso, ma questo forse non vale per tutti i file o il decodificatore potrebbe avere alcuni difetti che lo impediscono.

D'altra parte, se l'immagine viene successivamente recuperata dal file memorizzato nella cache, viene utilizzato BitmapFactory.decodeFile che non deve preoccuparsi dei dati in streaming e può accedere in modo casuale al file di immagine per decodificare il file JPEG. Se non hai bisogno degli aggiornamenti del display riga per riga durante il caricamento dell'immagine, ti suggerisco di eliminare questo percorso del codice e comunque di scaricare l'intera immagine prima di decodificarla.

+0

Ho avuto problemi simili anche con le decodifiche in volo. memorizzarli prima come file temporanei risolvono i problemi. – stpn108

Problemi correlati