標籤:android style class blog c code
原文出自:方傑|http://fangjie.sinaapp.com/?p=193 轉載請註明出處
最終效果示範:http://fangjie.sinaapp.com/?page_id=54
該項目代碼已經放到github:https://github.com/JayFang1993/SinaWeibo
一.ListView的圖片非同步載入
我們都知道對每一個Weibo Item都有帳戶圖片,而且每一條微博還可能帶有圖片。如果在載入列表的同時載入圖片,這樣有幾個缺點,第一很費事,介面卡住,使用者體驗很不好,第二Android在主線程中不能有網路操作,所以本身實現起來就很麻煩。所以我們才實現一個圖片非同步載入類。繼承自AsyncTask<String, Void, Bitmap>,重載其中的方法。doInBackground才是真正的非同步作業,做一些耗時的任務,這裡就是去伺服器上下載圖片,onPostExecute是在doInBackground結束後調用的,並傳入doInBackground的傳回值。
public AsyncImageLoader(ImageView image, LruCache<String, Bitmap> lruCache,int width,int height) { super(); this.image = image; this.lruCache = lruCache; this.width=width; this.height=width; } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; bitmap = GetUserInfo.getBitmap(params[0]); if(width!=0&height!=0) bitmap=GetUserInfo.scaleImg(bitmap, width, height); addBitmapToMemoryCache(params[0], bitmap); return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { image.setImageBitmap(bitmap); }
然後在WeiboAdapter中封裝一個介面 loadBitmap,載入圖片。
二.ListView圖片緩衝
ListView經常會上下滑動,而這些圖片載入任務就會反覆調用,這樣就很浪費。可以為圖片實現緩衝,當某個圖片載入過之後需要再次顯示只需要從記憶體中拿出來顯示就可以,不需要再去載入。緩衝其實有兩種緩衝,一種是記憶體緩衝,另一種是SD卡緩衝,即下載圖片到SD卡中。這裡我們只講記憶體緩衝。
結合上面的圖片非同步載入,整個圖片顯示的過程是這樣:當需要顯示圖片的時候,先去記憶體中尋找看是否有這種圖片的緩衝,有的話就直接顯示,沒有的話,去非同步載入,然後儲存到記憶體緩衝中,然後顯示。
完整的AsyncImageLoader.java代碼
package com.fangjie.weibo.util;import android.graphics.Bitmap;import android.os.AsyncTask;import android.support.v4.util.LruCache;import android.widget.ImageView;public class AsyncImageLoader extends AsyncTask<String, Void, Bitmap> { private ImageView image; private LruCache<String, Bitmap> lruCache; private int width; private int height; /** * 構造方法,需要把ImageView控制項和LruCache 對象傳進來 * @param image 載入圖片到此 {@code}ImageView * @param lruCache 緩衝圖片的對象 */ public AsyncImageLoader(ImageView image, LruCache<String, Bitmap> lruCache,int width,int height) { super(); this.image = image; this.lruCache = lruCache; this.width=width; this.height=width; } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; bitmap = GetUserInfo.getBitmap(params[0]); if(width!=0&height!=0) bitmap=GetUserInfo.scaleImg(bitmap, width, height); addBitmapToMemoryCache(params[0], bitmap); return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { image.setImageBitmap(bitmap); } //調用LruCache的put 方法將圖片加入記憶體緩衝中,要給這個圖片一個key 方便下次從緩衝中取出來 private void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) == null) { lruCache.put(key, bitmap); } } //調用Lrucache的get 方法從記憶體緩衝中去圖片 public Bitmap getBitmapFromMemoryCache(String key) { return lruCache.get(key); } }
在WeiboAdapter中的調用介面,loadBitmap
private final int maxMemory = (int) Runtime.getRuntime().maxMemory();//擷取當前應用程式所分配的最大記憶體 private final int cacheSize = maxMemory / 5;//只分5分之一用來做圖片緩衝 private LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>( cacheSize) { protected int sizeOf(String key, Bitmap bitmap) {//複寫sizeof()方法 // replaced by getByteCount() in API 12 return bitmap.getRowBytes() * bitmap.getHeight() / 1024; //這裡是按多少KB來算 } }; /** * * @param urlStr 所需要載入的圖片的url,以String形式傳進來,可以把這個url作為緩衝圖片的key * @param image ImageView 控制項 */ private void loadBitmap(String urlStr, ImageView image,int width,int height) { System.out.println(urlStr); AsyncImageLoader asyncLoader = new AsyncImageLoader(image, mLruCache,width,height);//什麼一個非同步圖片載入對象 Bitmap bitmap = asyncLoader.getBitmapFromMemoryCache(urlStr);//首先從記憶體緩衝中擷取圖片 if (bitmap != null) { image.setImageBitmap(bitmap);//如果緩衝中存在這張圖片則直接設定給ImageView } else { image.setImageResource(R.drawable.user_head);//否則先設定成預設的圖片 asyncLoader.execute(urlStr);//然後執行非同步任務AsycnTask 去網上載入圖片 } }
至此,微博首頁的微博列表載入也就全部完成。還有很多細小的點都沒講到,但是都有源碼,相信大家都能看得懂的。整個工程檔案:
代碼放在:http://git.oschina.net/fangjie/Sina-Weibo 效果展示:http://fangjie.sinaapp.com/?page_id=54
注:由於新浪微博的開發平台申請的應用沒有通過審核,所以不是所有的微博帳號都可以授權成功,需要測試的話可以找我,也可以在源碼中(com.fangjie.weibo.util.AuthUtil)改成你申請的appkey,appsecret。
微部落格戶端項目有時間再往下寫吧!