2012-04-25 32 views
5

Trước hết, tôi đã làm vài điều để hiển thị hình ảnh trong GridView thực hiện trơn tru khi di chuyểnCách tốt nhất để hiển thị hình ảnh theo quan điểm lưới được di chuyển trơn tru

1. hình ảnh tải từ internet trên sợi nền

AsyncTask acyncTask ; 
HandlerThread handlerThread ; 

URL imageUrl = new URL(link);<br> 
      HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); 
      conn.setConnectTimeout(30000); 
      conn.setReadTimeout(30000); 
      conn.setInstanceFollowRedirects(true); 
      InputStream is=conn.getInputStream(); 
      final Bitmap bitmap = BitmapFactory.decodeStream(is); 

2. làm bitmap để lấy mẫu mô để tiết kiệm bộ nhớ

final BitmapFactory.Options option = new BitmapFactory.Options(); 
    option.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(mFile.getPath(), 
      option); 
    option.inSampleSize = calculateInSampleSize(option , mSize , mSize); 
    option.inJustDecodeBounds = false; 
    option.inPurgeable = true ; 
    option.inDither = false ; 
    option.inScaled = false ; 
    option.inPreferredConfig = Bitmap.Config.ARGB_8888; 

3. làm cho một bộ nhớ cache để lưu giải mã bitmap

LruCache lruCache = new LruCache<String , Bitmap>(); 

trong baseadapter getView(); tôi sẽ lruCache.get(key) để có những bitmap giải mã

4. tải lười biếng khi bitmap được giải mã qua xử lý

Handler handler = new Handler(); 
     handler.post(new Runnable(){ 
      public void run(){ 
       imageView.setimageBitmap(bitmap); 
      } 
     }); 

Bây giờ tôi đang đối mặt với một vấn đề lớn, nó vẫn tụt hậu một chút khi tôi đang di chuyển Tôi có google về một cái gì đó có thể làm cho di chuyển tốt hơn, không biết thực sự cái gì có thể cải thiện hoặc vấn đề là đi ra từ nơi tôi có kiểm tra cho mỗi getView() chỉ dành cho tôi khoảng 2 ~ 6ms và nó sẽ hãy gọi mã số của tôi tới async tải hình thức công nhân mẫu hình ảnh, vì vậy tôi thực sự không biết tại sao một số ứng dụng có thể tải rất trơn tru? trường hợp của tôi là khi cuộn màn hình sẽ không giống như rất trơn tru là một số gợi ý có thể áp dụng?

chỉnh sửa: khi tôi đang cuộn, bitmap được tìm thấy trong bộ nhớ cache và hiển thị trên màn hình, nếu tôi cuộn nhanh, nó sẽ trông không đủ cuộn để hiển thị hình ảnh, nó sẽ làm cho cuộn của tôi không mượt mà, thậm chí tôi có bộ nhớ cache xuống bitmap trong bộ nhớ cache

đây là mã adapter:

if (convertView == null) { 
     convertView = layoutInflater.inflate(
       R.layout.row_display_image_grid, null); 
     viewHolder = new DisplayImageGridViewHolder(); 
     viewHolder.background = (RelativeLayout) convertView 
       .findViewById(R.id.background); 
     viewHolder.image = (ImageView) convertView.findViewById(R.id.image); 
     viewHolder.text = (TextView) convertView.findViewById(R.id.text); 
     viewHolder.position = position; 
     viewHolder.text.setEllipsize(TruncateAt.END); 
     viewHolder.text.setTypeface(typeFace); 
     viewHolder.image.setOnClickListener(this); 
     viewHolder.image.setOnLongClickListener(this); 
     convertView.setTag(viewHolder); 
    } else { 
     viewHolder = (DisplayImageGridViewHolder) convertView.getTag(); 
    } 

viewHolder.position = position; 
imageLoader.loadImage(imageLinkList.get(position), viewHolder.image); 
return convertView; 
+0

Bạn có thể đăng mã bộ chuyển đổi của mình không, cụ thể là phương thức getView().Đó là khả năng nhất mà sự chậm trễ di chuyển sẽ đến từ. –

+0

đã được thêm vào, tôi chỉ cần gọi phương thức để bắt đầu tải nhiệm vụ tại một chuỗi công nhân, tôi đã kiểm tra trước và sau phương pháp getview này, nó chỉ dành vài giây trong vài giây, bạn có nghĩ rằng setimagebitmap là vấn đề gì đó khi cuộn gridview – rex

+0

Mã của bạn vẫn còn một chút không rõ ràng. Bạn có thể đăng toàn bộ lớp ImageLoader của mình không. Tôi đang sử dụng mã rất giống nhau, có thể dựa trên cùng một ví dụ và có nó làm việc không có độ trễ. –

Trả lời

4

Dưới đây là một ví dụ về LazyLoader tôi sử dụng. Lưu ý Tôi đang sử dụng SoftReferences cho bitmap, điều này bây giờ được phục vụ tốt hơn bằng cách sử dụng LruCache.

Thao tác này sẽ tải hình ảnh không đồng bộ từ web/sdcard/bộ nhớ và tạo hiệu ứng mờ dần từ hình ảnh trình giữ chỗ.

public class ImageLoader { 

private static MemoryCacheNew memoryCache=new MemoryCacheNew(); 
private static FileCache fileCache; 

private static BitmapFactory.Options bitmapOptions; 

private static int mInSampleSize; 



public ImageLoader(Context context, int inSampleSize){ 


    fileCache=new FileCache(context);   

    context = null; 

    bitmapOptions = new BitmapFactory.Options(); 
    bitmapOptions.inSampleSize = mInSampleSize = inSampleSize; 
    bitmapOptions.inPreferredConfig = Config.RGB_565; 
    bitmapOptions.inInputShareable = true; 
    bitmapOptions.inDither = false; 

} 

final static int PLACEHOLDER_IMAGE = R.drawable.store_placeholder; 

public void DisplayImage(String url, ImageView imageView, boolean checkTags){ 

    try{ 

    new AsyncPhotoTask(imageView, url, checkTags).execute(); 

    }catch(Exception e){ 
     e.printStackTrace(); 
    } 

} 

public void DisplayImage(String url, ImageView imageView) 
{ 
     DisplayImage(url, imageView, true); 

} 


private static Bitmap getBitmap(String url) 
{ 
    File f=fileCache.getFile(url); 


    if(f!= null){ 
    //from SD cache 
    Bitmap b = decodeFile(f); 
    if(b!=null) 
     return b; 
    } 

    //from web 
    try { 
     Bitmap bitmap=null; 

     URL imageUrl; 

      imageUrl = new URL(url); 


     HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); 
     conn.setConnectTimeout(30000); 
     conn.setReadTimeout(30000); 
     InputStream is=conn.getInputStream(); 
     OutputStream os = new FileOutputStream(f); 
     Utils.CopyStream(is, os); 
     is.close(); 
     os.close(); 
     bitmap = decodeFile(f); 
     return bitmap; 
    } catch (Exception ex){ 
     ex.printStackTrace(); 
     return null; 
    } 
} 

//decodes image and scales it to reduce memory consumption 
private static Bitmap decodeFile(File f){ 
    try { 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, bitmapOptions); 

    } catch (FileNotFoundException e) { 

    } catch (OutOfMemoryError err){ 
     System.gc(); 
    } 

    return null; 
} 


private static class AsyncPhotoLoad extends AsyncTask<Void, Void, TransitionDrawable>{ 

    private Bitmap bmp; 
    private ImageView imageView; 
    private String url; 
    private boolean checkTags; 

    public AsyncPhotoLoad(ImageView imageView, String url, boolean checkTags 
      ){ 
     this.imageView = imageView; 
     this.url = url; 
     this.checkTags = checkTags; 
    } 

    @Override 
    protected TransitionDrawable doInBackground(Void... arg0) { 

     //check that this is the correct imageview 



     TransitionDrawable transition = null; 

     try{ 
      if(checkTags){ 
      String tag = (String)imageView.getTag();  
      if(!tag.equals(url)) 
       return null; 
      } 

     bmp = getBitmap(url); 

     if(bmp != null){ 
      memoryCache.put(url, bmp, mInSampleSize);  

      Drawable oldDrawable = imageView.getDrawable(); 

      if(!(oldDrawable instanceof TransitionDrawable)){ 

       Drawable layers[] = new Drawable[2];      
       layers[0] = imageView.getDrawable(); 
       layers[1] = new BitmapDrawable(bmp); 

       transition = new TransitionDrawable(layers); 

      } 



     } 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

     return transition; 
    } 

    @Override 
    protected void onPostExecute(TransitionDrawable result) { 
     if(result != null){ 
      try{    
       if(checkTags){      
         String tag = (String)imageView.getTag();  
         if(!tag.equals(url)){ 
          return; 
         } 
       } 

        imageView.setImageDrawable(result); 
        result.startTransition(300); 



      } catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } else { 
      if(checkTags){ 
      try{ 
       String tag = (String)imageView.getTag();  
       if(!tag.equals(url)) 
        return; 

      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
      } 


     } 
    } 

} 



private static class AsyncPhotoTask extends AsyncTask<Void, Void, Bitmap>{ 

    private ImageView imageView; 
    private String url; 
    private boolean checkTags; 


    public AsyncPhotoTask(ImageView imageView, String url, boolean checkTags){ 

     this.imageView = imageView; 
     this.url = url; 
     this.checkTags = checkTags; 
    } 


    @Override 
    protected Bitmap doInBackground(Void... params) { 
     try{ 
     if(checkTags) 
      imageView.setTag(url); 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

     return memoryCache.get(url, mInSampleSize); 
    } 


    @Override 
    protected void onPostExecute(Bitmap result) { 
     try{ 
     if(result!=null && !result.isRecycled()){ 


      imageView.setImageBitmap(result); 
     } 
     else 
     { 

      imageView.setImageResource(PLACEHOLDER_IMAGE);    
      new AsyncPhotoLoad(imageView, url, checkTags).execute();  

     }  

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 



} 





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

public static void clearMemory(){ 
    memoryCache.clear(); 
} 

public static class MemoryCacheNew { 
    private HashMap<String, CachedBitmap> cache=new HashMap<String, CachedBitmap>(); 

    public Bitmap get(String id, int sampleSize){ 
     if(!cache.containsKey(id)) 
      return null; 

     if(cache.get(id) == null) 
      return null; 

     if(cache.get(id).sampleSize != sampleSize) 
      return null; 

     SoftReference<Bitmap> ref = cache.get(id).softBitmap; 
     return ref.get(); 
    } 

    public void put(String id, Bitmap bitmap, int sampleSize){ 
     cache.put(id, new CachedBitmap(bitmap, sampleSize)); 
    } 

    public void clear() { 
     cache.clear(); 
    } 



    private static class CachedBitmap { 
     public SoftReference<Bitmap> softBitmap; 
     public int sampleSize; 

     public CachedBitmap(Bitmap bitmap, int sampleSize){ 
      this.softBitmap = new SoftReference<Bitmap>(bitmap); 
      this.sampleSize = sampleSize; 
     } 
    } 
} 


} 


public class FileCache { 

private File cacheDir; 

public FileCache(Context context){ 
    //Find the dir to save cached images 
    if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) 
     cacheDir=new File(context.getExternalCacheDir(),Consts.STORE_CACHE); 
    else 
     cacheDir=context.getCacheDir(); 
    if(!cacheDir.exists()) 
     cacheDir.mkdirs(); 
} 

public File getFile(String url){ 
    //I identify images by hashcode. Not a perfect solution, good for the demo. 
    String filename=String.valueOf(url.hashCode()); 
    File f = new File(cacheDir, filename); 
    return f; 

} 

public void clear(){ 
    File[] files=cacheDir.listFiles(); 
    for(File f:files) 
     f.delete(); 
} 

} 

Bạn gọi nó là như thế này:

imageLoader.DisplayImage(url, holder.image); 
+0

vâng, bạn cũng đang sử dụng mã tương tự, nhưng nó không thể giúp tôi, xin lỗi – rex

0

Cố gắng đảm bảo rằng mỗi bitmap kích thước tối ưu ... họ nên được về kích thước của container. Quy mô chúng xuống càng nhiều càng tốt trước khi gửi chúng qua RemoteViews. Bạn có thể tính toán kích thước widget bằng cách sử dụng onAppWidgetOptionsChanged.

Ngoài ra, hãy thử sử dụng setImageViewUri (với nhà cung cấp nội dung) thay vì setImageViewBitmapcho hiệu suất tối ưu nhất.

Các vấn đề liên quan