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(new
String[]{"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());
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值