listview异步加载图片
一般,我們使用listview加載圖片時,有很多的jar包已經封裝的很好,我們只需要知道怎么使用就可以,比如常用的imageLoader,使用非常的方便。但是,我們也要知道自己怎么用listview異步加載圖片。昨天,在網上找了資料,自己總算是做出來了。
1.新建一個普通的listview,每個item里存放一個imageview和textView,然后做好一個適配器adapter。
adapter的getview()和普通的listview一樣,編寫很簡單。
public View getView(int position, View convertView, ViewGroup parent) {ImageView imageView = null; TextView textView = null; if (convertView == null) {convertView = layoutInflater.inflate(listviewItem, null); // 獲取條目的view對象 imageView = (ImageView) convertView.findViewById(R.id.imageView); textView = (TextView) convertView.findViewById(R.id.textView); convertView.setTag(new DataWrapper(imageView, textView)); } else {DataWrapper dataWrapper = (DataWrapper) convertView.getTag(); imageView = dataWrapper.imageView; textView = dataWrapper.textView; imageView.setTag(position); }Contact contact = data.get(position); textView.setText(contact.name); //=====初始化時加載圖片 if (isInit==false){asyncImageLoad(imageView, contact.image); }retu?
在getView里,asyncImageLoad(imageView, contact.image);是用來異步加載圖片的,每次調用getView()時,通過傳遞imageview和圖片的網絡地址,開啟一個異步任務,去網絡下載圖片,下載后,首先存入緩存,然后存入sd卡,下載完成后顯示在listview上,下載調用時會先從軟引用尋找圖片,用的話直接顯示圖片,如果沒有,則從sd卡找圖片,有的話顯示圖片,如果沒有,則進行網絡請求。
2.編寫異步請求的代碼。
private void asyncImageLoad(ImageView imageView, String path) {if (imageCache.containsKey(path)) {SoftReference<Drawable> softReference = imageCache.get(path); Drawable drawable = softReference.get(); if (drawable != null) {imageView.setImageDrawable(drawable); Log.e("Test_path",""+path); return; }}Log.e("Test_path2",""+path); AsyncImageTask asyncImageTask = new AsyncImageTask(imageView); asyncImageTask.execute(path); }這其中用到一個異步加載的類AsyncImageTask,當每次請求網絡圖片時,獲得圖片后,會把圖片存入軟引用。
private final class AsyncImageTask extends AsyncTask<String, Integer, Uri> {private ImageView imageView; private String imageUrl; public AsyncImageTask(ImageView imageView) {this.imageView = imageView; }protected Uri doInBackground(String... params) {// 子線程中執行的 try {imageUrl=params[0]; return ContactService.getImage(params[0], cache); } catch (Exception e) {e.printStackTrace(); }return null; }protected void onPostExecute(Uri result) {// 運行在主線程 if (result != null && imageView != null) imageView.setImageURI(result); Drawable drawable =imageView.getDrawable(); imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); }}?
在doInBackground()內開啟了線程,進行網絡請求。
public static Uri getImage(String path, File cacheDir) throws Exception{// path -> MD5 ->32字符串.jpg File localFile = new File(cacheDir, MD5.getMD5(path)+ path.substring(path.lastIndexOf("."))); if(localFile.exists()){return Uri.fromFile(localFile); }else{Log.e("Test_MD5",""+path); HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); if(conn.getResponseCode() == 200){FileOutputStream outStream = new FileOutputStream(localFile); InputStream inputStream = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; while( (len = inputStream.read(buffer)) != -1){outStream.write(buffer, 0, len); }inputStream.close(); outStream.close(); return Uri.fromFile(localFile); }}return null; }getImage()內用get()去請求圖片,然后獲得圖片后,存入sd卡,然后返回圖片存入文件的URI。
?
然后,AsyncImageTask的onPostExecute()獲得URI,然后通過imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));設置圖片。
?
這樣就完成了圖片的異步加載。這時滑動listview,會發現滑動有卡頓,所以可以設置listview的滑動監聽。
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {@Override public void onScrollStateChanged(AbsListView absListView, int scrollState) {switch (scrollState) {case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:// 滑動停止 isInit=true; for (; start_index < end_index; start_index++) {ImageView imageView = (ImageView) mListView.findViewWithTag(start_index); Contact contact = ContactAdapter.this.data.get(start_index); if (imageView!=null){asyncImageLoad(imageView, contact.image); }else {Log.e("Test2",""+imageView); }}break; default:break; }}@Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {start_index = firstVisibleItem; end_index = firstVisibleItem + visibleItemCount; } });?
其中ImageView imageView = (ImageView) mListView.findViewWithTag(start_index);是因為在getview()內我設置了imageview的Tag.imageView.setTag(position);然后在空閑的狀態下調用異步加載圖片。
這樣就完成了異步加載,與滑動不加載的功能。
總結
以上是生活随笔為你收集整理的listview异步加载图片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VWware安装ubuntu设置静态IP
- 下一篇: android 密码加密