【第二篇】Volley的使用之加载图片
Volley加载图片有两种方式:
1,ImageRequest 来对网络图片进行请求,放入请求队列,获取后现在在控件上面。
2,NetworkImageView 最为自定义控件来自动加载网络图片。
3,imageloader,对图片大小,质量格式控制来按需加载图片。
下面分别举例子说明使用:
ImageRequest的使用来加载图片:
首先设计界面,是个Gridview来加载图片:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <GridView android:id="@+id/gvImages" android:layout_width="match_parent" android:layout_height="match_parent" android:numColumns="3" android:stretchMode="columnWidth" android:verticalSpacing="10dp" android:horizontalSpacing="10dp"> </GridView> </RelativeLayout>
GridView的item布局文件如下,上面是图片,下面是文字说明:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/ivImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:contentDescription="test" /> <TextView android:id="@+id/tvDesc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivImage" android:layout_centerHorizontal="true" /> </RelativeLayout>
下面是主要的图片加载的逻辑代码,流程如下:
1,创建请求队列mQueue;
2,创建ImageRequest 请求,并进行配置,并将请求放入请求队列mqueue中去;
3,ImageRequest只有一个构造方法:对图片大小和图片格式进行设置;
/** * Creates a new image request, decoding to a maximum specified width and * height. If both width and height are zero, the image will be decoded to * its natural size. If one of the two is nonzero, that dimension will be * clamped and the other one will be set to preserve the image's aspect * ratio. If both width and height are nonzero, the image will be decoded to * be fit in the rectangle of dimensions width x height while keeping its * aspect ratio. * * @param url URL of the image 网络图片Url * @param listener Listener to receive the decoded bitmap 接收网络图片的bitmap回调参数 * @param maxWidth Maximum width to decode this bitmap to, or zero for none 宽 * @param maxHeight Maximum height to decode this bitmap to, or zero for 高 * none * @param decodeConfig Format to decode the bitmap to 编码质量的配置 * @param errorListener Error listener, or null to ignore errors 加载图片失败的回调 */ public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight, Config decodeConfig, Response.ErrorListener errorListener) { super(Method.GET, url, errorListener); setRetryPolicy( new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT)); mListener = listener; mDecodeConfig = decodeConfig; mMaxWidth = maxWidth; mMaxHeight = maxHeight; }
package com.soyoungboy.volleydemo; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageRequest; import com.android.volley.toolbox.Volley; /** * Volley使用demo * * @author soyoungboy */ public class MainActivity extends Activity { private static final String[] URLS = { "//img-my.csdn.net/uploads/201403/03/1393854094_4652.jpg", "//img-my.csdn.net/uploads/201403/03/1393854084_6138.jpg", "//img-my.csdn.net/uploads/201403/03/1393854084_1323.jpg", "//img-my.csdn.net/uploads/201403/03/1393854084_8439.jpg", "//img-my.csdn.net/uploads/201403/03/1393854083_6511.jpg", "//img-my.csdn.net/uploads/201403/03/1393854083_2323.jpg" }; private static final String[] DESCS = { "photo1", "photo2", "photo3", "photo4", "photo5", "photo6" }; private RequestQueue mQueue; private GridView gvImages; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gvImages = (GridView) findViewById(R.id.gvImages); GridAdapter adpater = new GridAdapter(); gvImages.setAdapter(adpater); mQueue = Volley.newRequestQueue(this); } class GridAdapter extends BaseAdapter { private LayoutInflater layoutInflater; public GridAdapter() { layoutInflater = LayoutInflater.from(MainActivity.this); } @Override public int getCount() { return URLS.length; } @Override public Object getItem(int position) { return URLS[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { viewHolder = new ViewHolder(); convertView = layoutInflater.inflate(R.layout.grid_item, null); viewHolder.ivImage = (ImageView) convertView .findViewById(R.id.ivImage); viewHolder.tvDesc = (TextView) convertView .findViewById(R.id.tvDesc); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } loadImgByVolley(URLS[position], viewHolder.ivImage); viewHolder.tvDesc.setText(DESCS[position]); return convertView; } } static class ViewHolder { ImageView ivImage; TextView tvDesc; } public void loadImgByVolley(String imgUrl, final ImageView imageView) { ImageRequest imgRequest = new ImageRequest(imgUrl, new Response.Listener<Bitmap>() { /** * 加载成功 * @param arg0 */ @Override public void onResponse(Bitmap arg0) { imageView.setImageBitmap(arg0); } }, 300, 200, Config.ARGB_8888, new ErrorListener() { //加载失败 @Override public void onErrorResponse(VolleyError arg0) { imageView.setImageResource(R.drawable.ic_launcher); } }); //将图片加载放入请求队列中去 mQueue.add(imgRequest); } }
效果:
NetworkImageView加载图片:
首先在布局中使用NetWorkImageView:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.android.volley.toolbox.NetworkImageView android:id="@+id/load_img" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
java代码里面实现:
package com.soyoungboy.volleydemo; import android.app.Activity; import android.os.Bundle; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.NetworkImageView; import com.android.volley.toolbox.Volley; public class NetworkImageViewActivity extends Activity { private NetworkImageView load_img; private ImageLoader imageLoader; private RequestQueue requestQueue; private LruImageCache lruImageCache; private static final String IMGURL = "http://imgsrc.baidu.com/forum/w%3D580/sign=f96acdfc08f79052ef1f47363cf1d738/cb2fc65c10385343223c39ce9213b07ecb808870.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_networkimageview); load_img = (NetworkImageView) findViewById(R.id.load_img); lruImageCache = LruImageCache.getInstance(); requestQueue = Volley.newRequestQueue(this); imageLoader = new ImageLoader(requestQueue, lruImageCache); load_img.setImageUrl(IMGURL, imageLoader); } }
LruImageCache.java缓存类:
package com.soyoungboy.volleydemo; import android.graphics.Bitmap; import android.support.v4.util.LruCache; import com.android.volley.toolbox.ImageLoader.ImageCache; public class LruImageCache implements ImageCache{ private static LruCache<String, Bitmap> mMemoryCache; private static LruImageCache lruImageCache; private LruImageCache(){ // Get the Max available memory int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize){ @Override protected int sizeOf(String key, Bitmap bitmap){ return bitmap.getRowBytes() * bitmap.getHeight(); } }; } public static LruImageCache getInstance(){ if(lruImageCache == null){ lruImageCache = new LruImageCache(); } return lruImageCache; } @Override public Bitmap getBitmap(String arg0) { return mMemoryCache.get(arg0); } @Override public void putBitmap(String arg0, Bitmap arg1) { if(getBitmap(arg0) == null){ mMemoryCache.put(arg0, arg1); } } }
其中LruImageCache是个Lru算法类,主要用于处理缓存的大小问题,可以避免加载图片的时候oom的问题,ImaageLoader是volley提供的另外一种加载图片的方式。最后通过setImageUrl(String url, ImageLoader imageLoader)来进行加载。
NetworkImageView的优势在于他能够根据组件的大小自动进行图片的大小缩放处理。后面文章会在源码分析中进行讲解。
效果:
ImageLoader加载图片:
帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
1,创建请求队列;
2,创建imageloader对象,其中imageloader的构造方法第二个参数为imageCache的实现类,实现图片缓存的算法类。
3,创建imagelistener对象,主要设置图片加载失败和加载过程中的图片设置。
界面如上面第一个的界面activity_main.xml;
这里主要看下逻辑:
package com.soyoungboy.volleydemo.activity; import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.ImageLoader.ImageListener; import com.android.volley.toolbox.Volley; import com.soyoungboy.volleydemo.LruImageCache; import com.soyoungboy.volleydemo.R; public class ImageLoaderActivity extends Activity { private GridView gvImages; private static final String[] URLS = { "//img-my.csdn.net/uploads/201403/03/1393854094_4652.jpg", "//img-my.csdn.net/uploads/201403/03/1393854084_6138.jpg", "//img-my.csdn.net/uploads/201403/03/1393854084_1323.jpg", "//img-my.csdn.net/uploads/201403/03/1393854084_8439.jpg", "//img-my.csdn.net/uploads/201403/03/1393854083_6511.jpg", "//img-my.csdn.net/uploads/201403/03/1393854083_2323.jpg" }; private static final String[] DESCS = { "photo1", "photo2", "photo3", "photo4", "photo5", "photo6" }; private RequestQueue mQueue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gvImages = (GridView) findViewById(R.id.gvImages); mQueue = Volley.newRequestQueue(this); GridAdapter adpater = new GridAdapter(); gvImages.setAdapter(adpater); } class GridAdapter extends BaseAdapter { private LayoutInflater layoutInflater; private ImageLoader imageLoader; public GridAdapter() { layoutInflater = LayoutInflater.from(ImageLoaderActivity.this); imageLoader = new ImageLoader(mQueue, LruImageCache.getInstance()); } @Override public int getCount() { return URLS.length; } @Override public Object getItem(int position) { return URLS[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { viewHolder = new ViewHolder(); convertView = layoutInflater.inflate(R.layout.grid_item, null); viewHolder.ivImage = (ImageView) convertView .findViewById(R.id.ivImage); viewHolder.tvDesc = (TextView) convertView .findViewById(R.id.tvDesc); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } loadImgByVolley(URLS[position], viewHolder.ivImage); viewHolder.tvDesc.setText(DESCS[position]); return convertView; } private void loadImgByVolley(String string, ImageView ivImage) { ImageListener listener = ImageLoader.getImageListener(ivImage, R.drawable.ic_launcher, R.drawable.ic_launcher); imageLoader.get(string, listener); } } static class ViewHolder { ImageView ivImage; TextView tvDesc; } }
界面效果: