Android批量圖片載入經典系列——Volley架構實現多布局的新聞列表,
Volley是Google 2013年發布的實現Android平台上的網路通訊庫,主要提供網路通訊和圖片下載的解決方案,比如以前從網上下載圖片的步驟可能是這樣的流程:
在ListAdapter的getView()裡開始映像的讀取。
通過AsyncTask等機制使用HttpURLConnection從伺服器去的圖片資源,在AsyncTask的onPostExecute()裡設定相應ImageView的屬性.而在Volley下,只需要ImageLoader即可實現。
案例介紹——現圖片新聞瀏覽:
1、 RequestQueue 請求隊列將StringRequest請求放入隊列,並進行非同步處理,主要代碼:
//建立RequestQueue,可發送非同步請求RequestQueue mRequestQueue=Volley.newRequestQueue(this);//StringRequest request=new StringRequest(…);//建立一個用戶端請求mRequestQueue.add(request);//將請求加到隊列,將非同步執行請求
2、ImageLoader 實現緩衝並非同步載入網狀圖片
//建立ImageLoader,用於將圖片存入緩衝和從緩衝中取出圖片//第一個參數為之前建立的RequestQueue對象//第二參數為圖片緩衝設定,詳解見BitmapCache代碼ImageLoader mImageLoader=new ImageLoader(mRequestQueue,new BitmapCache());//載入圖片,先從記憶體中載入,記憶體沒有再從網路載入//url:圖片網路路徑 //view 顯示圖片的ImageView控制項,R.drawable.default未載入完成顯示的預設圖片 ,R.drawable.error載入失敗顯示的圖片 mImageLoader.get(url,ImageLoader.getImageListener(view, R.drawable.default, R.drawable.error));
註:服務端環境需要自行搭建
1、 BitmapCache和SunNewsApplication組件:
(1)BitmapCache:
public class BitmapCache implements ImageCache{ private LruCache<String, Bitmap> mCache; public BitmapCache(){ // 擷取到可用記憶體的最大值,使用記憶體超出這個值會引起OutOfMemory異常 // 使用最大可用記憶體值的1/8作為緩衝的大小。 int maxsize=(int)(Runtime.getRuntime().maxMemory()/1024)/8; mCache=new LruCache<String, Bitmap>(maxsize){ // 重寫此方法來衡量每張圖片的大小,預設返回圖片數量 @Override protected int sizeOf(String key, Bitmap value) { return super.sizeOf(key, value); } }; } /** * 擷取緩衝中圖片 */ @Override public Bitmap getBitmap(String key) { return mCache.get(key); } /** * 存入緩衝 */ @Override public void putBitmap(String key, Bitmap bitmap) { if(bitmap!=null)mCache.put(key, bitmap); }}
(2)SunNewsApplication:
public class SunNewsApplication extends Application {private ImageLoader mImageLoader; private RequestQueue mRequestQueue;public void onCreate(){//建立RequestQueue,可發送非同步請求mRequestQueue=Volley.newRequestQueue(this);//建立ImageLoader,用於將圖片存入緩衝和從緩衝中取出圖片mImageLoader=new ImageLoader(mRequestQueue,new BitmapCache()); } public ImageLoader getmImageLoader() { return mImageLoader; } public RequestQueue getmRequestQueue() { return mRequestQueue; }}
2、MoreStyleNewsListViewAdapter代碼:
public class MoreStyleNewsListViewAdapter extends BaseAdapter { private Activity mActivity; private List<NewsItem> newsList; private ImageLoader imageLoader; public MoreStyleNewsListViewAdapter(Activity mActivity,List<NewsItem> newsList){ this.mActivity=mActivity; this.newsList=newsList; imageLoader=((SunNewsApplication)mActivity.getApplication()).getmImageLoader(); } private final int TYPE_COUNT=2; /** * 返回資料項目的顯示類型資料 */ @Override public int getItemViewType(int position) { return newsList!=null?newsList.get(position).getStyle():-1; } /** * 傳回型別個數 */ @Override public int getViewTypeCount() { return TYPE_COUNT; } @Override public int getCount() { return newsList.size(); } @Override public Object getItem(int position) { return newsList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder=null; NewsItem item=newsList.get(position); if(convertView==null){ holder=new ViewHolder(); //將layout.xml轉換為View switch(item.getStyle()){ case 0: convertView=LayoutInflater.from(mActivity).inflate(R.layout.news_item1, null); holder.ivImg1=(ImageView)convertView.findViewById(R.id.ivNewsImg); break; case 1: convertView=LayoutInflater.from(mActivity).inflate(R.layout.news_item2, null); holder.ivImg1=(ImageView)convertView.findViewById(R.id.ivImg1); holder.ivImg2=(ImageView)convertView.findViewById(R.id.ivImg2); holder.ivImg3=(ImageView)convertView.findViewById(R.id.ivImg3); break; } holder.tvTilte=(TextView)convertView.findViewById(R.id.tvTitle); convertView.setTag(holder);//記錄個標識 }else{ holder=(ViewHolder)convertView.getTag(); } //向ui元素繫結資料 holder.tvTilte.setText(item.getTitle());//載入圖片,先從記憶體中載入,記憶體沒有再從網路載入 imageLoader.get(item.getImgUrl()[0], ImageLoader.getImageListener(holder.ivImg1, R.drawable.default_big, R.drawable.default_big)); switch(item.getStyle()){ case 1:imageLoader.get(item.getImgUrl()[1], ImageLoader.getImageListener(holder.ivImg2, R.drawable.default_big, R.drawable.default_big)); imageLoader.get(item.getImgUrl()[2], ImageLoader.getImageListener(holder.ivImg3, R.drawable.default_big, R.drawable.default_big)); break; } Log.d("jereh","getView()"); return convertView; } private class ViewHolder{ private TextView tvTilte; private ImageView ivImg1; private ImageView ivImg2; private ImageView ivImg3; }}
3、MainActivity代碼
public class MainActivity extends Activity { private RadioGroup rgChannel; private List<NewsItem> newsList=new ArrayList<NewsItem>(); private MoreStyleNewsListViewAdapter adapter; private ListView newsListView; private RequestQueue queue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); queue=((SunNewsApplication)super.getApplication()).getmRequestQueue(); initView(); requestData(); } private void initView(){ rgChannel=(RadioGroup)super.findViewById(R.id.rgChannel); rgChannel.check(R.id.rbToday); newsListView=(ListView)super.findViewById(R.id.lvNews); adapter=new MoreStyleNewsListViewAdapter(this,newsList); newsListView.setAdapter(adapter); } /** * 非同步請求獲得網路資料 */ private void requestData(){ String url="http://192.168.0.107:8080/21-sun/NewsListServlet"; StringRequest request=new StringRequest(Method.GET,url, new Response.Listener<String>() { @Override public void onResponse(String ret) {//請求成功調用並返回結果 Gson gson=new Gson(); List list=gson.fromJson(ret, new TypeToken<ArrayList<NewsItem>>(){}.getType()); newsList.addAll(list); adapter.notifyDataSetChanged(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {//請求失敗調用 Log.d("jereh", "網路載入失敗!"); } }); queue.add(request);//將請求加到隊列,將非同步執行請求 }}
4、NewsItem實體類
public class NewsItem {private String title;//新聞標題 private int style; //0:普通 1:多圖 2: private String[] imgUrl;//新聞圖片 …//省略setter/getter}
5、服務端NewsListServlet代碼
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/json;charset=utf-8"); List<NewsItem> newsList=new ArrayList<NewsItem>(); NewsItem item1=new NewsItem(); item1.setTitle("英達成唯一獲新疆最高信用等級的養護施工企業"); item1.setStyle(0); item1.setImgUrl( new String[]{"http://news.21-sun.com/UserFiles/x_Image/x_20150624164627_0.jpg"}); newsList.add(item1);… NewsItem item4=new NewsItem(); item4.setTitle("德工2015路面機械品質萬裡行活動走進河南"); item4.setStyle(1);item4.setImgUrl(newString[]{"http://news.21-sun.com/UserFiles/x_Image/x_20150624101251_0.jpg", "http://news.21-sun.com/UserFiles/x_Image/x_20150624080852_0.jpg", "http://news.21-sun.com/UserFiles/x_Image/x_20150623141354_0.jpg"}); newsList.add(item4); NewsItem item5=new NewsItem(); item5.setTitle("德州寶鼎總經理王桂清:實在女人愛學習"); item5.setStyle(0); item5.setImgUrl(new String[]{"http://news.21-sun.com/UserFiles/x_Image/x_20150624123300_0.jpg"}); newsList.add(item5); JSONArray jsonArr=JSONArray.fromObject(newsList); System.out.println(jsonArr);response.getWriter().print(jsonArr.toString()); }
想要瞭解更多內容的小夥伴,可以點擊查看源碼,親自運行測試。
疑問諮詢或技術交流,請加入官方QQ群: (452379712)
作者:傑瑞教育
出處:http://www.cnblogs.com/jerehedu/
本文著作權歸煙台傑瑞教育科技有限公司和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。