你的位置:首页 > 操作系统

[操作系统]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.    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群:JRedu技术交流 (452379712)

 

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。