編輯:關於Android編程
本篇博客總結了慕課網關於異步加載圖片的知識要點,和大家一起分享,有感覺聽得不連貫的可以來看看。
看完本篇博客,你將學習到下面的知識:
1.怎樣將一個url(也可以說是一個InputStream)轉換為一個json字符串信息。
2.怎樣運用插件寫一個我認為完美的model類來為解析json做准備。
3.AsyncTask的基本用法。
4.Gosn的基本用法。
5.Adapter的常用優化寫法。
6.通過LruCache緩存已經加載的圖片。
7.listview高效加載復雜item布局。
8.編寫json實體類的AS小插件。
好了,直接上代碼,代碼裡面有詳細的解釋。
package com.robin.loadimageinlistview; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ListView; import com.google.gson.Gson; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.List; public class MainActivity extends AppCompatActivity { private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.lv_main); String URL1 = "http://www.imooc.com/api/teacher?type=4&num=30"; new MyAsyncTask().execute(URL1); } class MyAsyncTask extends AsyncTask> {//(知識點3) @Override protected List doInBackground(String... params) { return getJsonData(params[0]); } @Override protected void onPostExecute(List beanDatas) { super.onPostExecute(beanDatas); NewsAdapter adapter = new NewsAdapter(MainActivity.this, beanDatas, listView); listView.setAdapter(adapter); } } /** * 通過URL獲取json字符串(知識點2) * * @param url * @return List */ private List getJsonData(String url) { String jsonString = null; try { jsonString = readStream(new URL(url).openStream()); } catch (IOException e) { e.printStackTrace(); } Gson gson = new Gson(); if(jsonString==null||"".equals(jsonString))return null;//如果jsonString返回有問題,就不解析了。 NewsBean newsBean = gson.fromJson(jsonString, NewsBean.class);//(知識點4)需要將Gosn的包導入進project中。怎麼導,就不詳細說了,去Google return newsBean.getData(); } /** * 怎樣將一個url(也可以說是一個InputStream)轉換為一個json字符串信息。(知識點1) * * @param is * @return String */ private String readStream(InputStream is) { String result = ""; InputStreamReader isr; String line; try { isr = new InputStreamReader(is, "utf-8");//字節流轉化為字符流 BufferedReader br = new BufferedReader(isr); while ((line = br.readLine()) != null) { result += line; } } catch (IOException e) { e.printStackTrace(); } return result; } }
package com.robin.loadimageinlistview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import java.util.List; public class NewsAdapter extends BaseAdapter implements AbsListView.OnScrollListener{ private List對知識點7的一點解釋,當item布局非常復雜的時候,這是用戶區頻繁滾動listview,listview會頻繁調用getView方法去獲取item,導致卡頓,然而,平常的使用過程中,我們發現一般用戶滾動的時候不太注意內容,停止滾動的時候才回去看內容,因此我們考慮如果將顯示內容的權利從getView中移交給滾動事件處理的話,這個問題就能得到解決。newsBeans; private LayoutInflater mInflater; private ImageLoader imageLoader; private int mStart,mEnd; public static String[] URLS;//存放要加載的圖片的url private boolean isFirst = false;//控制第一次進入listview的時候加載數據 public NewsAdapter(Context context, List newsBeans, ListView listView) {//初始化數據 this.newsBeans = newsBeans; this.mInflater = LayoutInflater.from(context); imageLoader = new ImageLoader(listView);// 確保只有一個LruCache URLS = new String[newsBeans.size()]; for (int i=0;i (知識點7) if(scrollState==SCROLL_STATE_IDLE){//停止滾動,加載可見項 imageLoader.loadImage(mStart,mEnd); }else{//停止加載 imageLoader.cancelAllTask(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {//整個滑動的時候都會調用 mStart = firstVisibleItem;//第一個可見元素 mEnd =firstVisibleItem+visibleItemCount;//最後一個可見元素=第一個可見元素+可見元素的數量 if(isFirst && visibleItemCount > 0){//第一次加載的時候調用,顯示圖片 imageLoader.loadImage(mStart,mEnd); isFirst=false; } } class ViewHolder{ public TextView tvTitle; public TextView tvContent; public ImageView ivIcon; } }
接下來上最重要的控制圖片緩存以及加載的類
package com.robin.loadimageinlistview; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.LruCache; import android.widget.ImageView; import android.widget.ListView; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; import java.util.Set; public class ImageLoader { private LruCachecache;//用於緩存圖片 private ListView listView; private Set mTask;//管理AsyncTask public ImageLoader(ListView listView) {//初始化一些數據 this.listView = listView; this.mTask = new HashSet<>(); int maxMemry = (int) Runtime.getRuntime().maxMemory();//獲取當前應用可用的最大內存 int cacheSize = maxMemry/4;//以最大的四分之一作為可用的緩存大小 this.cache = new LruCache (cacheSize){//初始化LruCache @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount();//每次存入緩存的大小,即bitmap的大小 } }; } /** * 將內容保存到LruCache * @param url * @param bitmap */ public void addBitmapToCache(String url,Bitmap bitmap){ if(getBitmapFromCache(url)==null){//如果沒有保存的話就保存。 cache.put(url,bitmap); } } /** * 從LruCache中獲取bitmap * @param url * @return Bitmap */ public Bitmap getBitmapFromCache(String url){ return this.cache.get(url); } /** * 將圖片url轉化為bitmap * @param urlString * @return Bitmap */ public Bitmap getBitmapFromUrl(String urlString){ Bitmap bitmap; InputStream is=null; try { URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); is = new BufferedInputStream(connection.getInputStream()); bitmap = BitmapFactory.decodeStream(is); connection.disconnect(); return bitmap; } catch (IOException e) { e.printStackTrace(); }finally { try { if(is!=null){ is.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } public void showImageByAsyncTask(ImageView imageView,String url){//改進之後,獲取圖片的控制權由原來getview改成了滾動狀態。 Bitmap bitmap = getBitmapFromCache(url);//從緩存中獲取圖片 if(bitmap==null){//如果沒有就設置默認的圖片 imageView.setImageResource(R.mipmap.ic_launcher); }else{//如果有就設置當前的圖片 imageView.setImageBitmap(bitmap); } } private class NewsAsyncTask extends AsyncTask { private String url; public NewsAsyncTask(String url) { this.url = url; } @Override protected Bitmap doInBackground(String... params) { String url = params[0]; Bitmap bitmap = getBitmapFromUrl(url);//獲取網絡圖片 if(bitmap!=null){ addBitmapToCache(url,bitmap); //將不在緩存的圖片加載的緩存中去 } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); ImageView imageView =(ImageView) listView.findViewWithTag(url); if(imageView!=null&&bitmap!=null){//判斷這個url所對應的imageview是否對應,對應的話才設置圖片, imageView.setImageBitmap(bitmap); } } } /** * 加載從start到end的所有圖片 * @param start * @param end */ public void loadImage(int start,int end){ for (int i= start;i 最後送上一個小插件(知識點8),只恨自己執導的太晚,要是有個這個神奇,實體類就不在這麼難寫了。再次分享給大家,尤其是企業開發的時候,經常能用到,上 git地址,包括用法,安裝很詳細的。 https://github.com/zzz40500/GsonFormat
好了,大概就這些了,上傳一張效果圖
為了應用的推廣、傳播,很多的應用中都有“分享”功能,一個按鈕,點擊後會出現短信、微博等等一切實現了分享功能的應用列表。這一篇文章主要介紹怎麼調用分享功能和怎麼實現分享接口
打開微信朋友圈,就被一組微信款性格標簽刷爆,在別人眼裡你究竟是一個怎樣的人呢?踏實務實還是傲嬌?這麼好玩的微信朋友圈性格標簽怎麼弄?下面小編就告訴大家微信朋
如果你是小米手機或小米MIUI系統的用戶,充值話費可以很簡單,你知道嗎?還在打開電腦、登陸淘寶,搜索充值話費的店嗎?看看小米MIUI系統是怎麼在撥號界面輕松
臨近畢業,各種事情各種忙。我也沒有認真專注寫過博客,最近仔細看了Volley框架的使用及其源碼,思前想後,想挑戰一下自己,還是寫一篇博客來分享,如有錯誤,歡迎吐槽。Vol