Android-GridView实例(优化列表数据加载,图片圆角,LruCache优化)

来源:互联网 发布:在计算机领域 数据是 编辑:程序博客网 时间:2024/05/21 11:09

1.回顾

  上篇学习了,gridview 加载数据;图片请求,LruCache 缓存实现;

  上篇遗留问题:

    (1)优化列表数据加载:当滑动到列表哪里,加载这里的图片;

    (2)LruCache 缓存 实现 sizeof 方法;(一定要实现)

2.重点

  (1)LruCahce 缓存 修复

  (2)优化列表数据加载:AsyncTask 异步加载图片

  (3)圆角图片实现

3.   效果和对比

   背景:

    (1)没有LruCahce 缓存实现:当在滑动的时候,一直在请求图片,这是不可取的,因为消耗流量太厉害;

    (2)有LruCache缓存,没有优化的时候:当在滑动的时候,图片会加载到GridView中,当图片量很大的时候,会通通加载到缓存中;还有就是,在滑动过程中,如果边滑动,边加载,gridview可能发生卡顿现象;

    (3)LruCache缓存和优化列表实现 :缓存就不说了,这是必须的;数据加载优化,当滑动的时候,停止任务加载;当停止滑动的时候,进行图片数据加载;也就是说,停止滑动的时候,加载任务就当前页面中的几张图片加载任务;

     (4)效果图



4.LruCache 优化实现

   在使用LrcCache的时候,必须实现 sizeOf 方法,来计算大小;

package com.example.Adapter;import java.util.ArrayList;import java.util.List;import android.graphics.Bitmap;import android.support.v4.util.LruCache;public class ImageCache {/** * 缓存类 LruCache */private static  LruCache<String,Bitmap> imgCache;/** * 实例 */private static ImageCache instance;/** * 判断key 是否存在 */private static List<String> lruKeys;public ImageCache() {// 初始化 ,拿可用 内存的8分之一int maxMemory=(int) Runtime.getRuntime().maxMemory();int cacheMemory=maxMemory/8;imgCache=new LruCache<String, Bitmap>(cacheMemory){@Overrideprotected int sizeOf(String key, Bitmap value) {// 必须重写此方法,计算bitmap的大小return value.getRowBytes()*value.getHeight();}};lruKeys=new ArrayList<String>();}/** * 单例模式 创建 ImageCache 缓存类 * @return */public static ImageCache getinstance(){if(instance==null){instance=new ImageCache();return instance;   }else{   return instance;   }}/** * 添加缓存 * @param key * @param bitmap */public  void setCache(String key,Bitmap bitmap){imgCache.put(key, bitmap);lruKeys.add(key);}/** * 得到缓存 * @param key * @return */public  Bitmap getCache(String key){return imgCache.get(key);}/** * 判断是否存在key * @param key * @return */public  boolean isKey(String key){return lruKeys.contains(key);}}

5.Adapter实现

   (1)实现 OnScrollListener 接口;

   (2)在Adapter里进行setTag操作;

   (3)通过AsyncTask实现异步加载图片:优点 加载任务的可控性;

package com.example.Adapter;import java.util.List;import android.annotation.SuppressLint;import android.content.Context;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView;import android.widget.ImageView.ScaleType;import android.widget.TextView;import com.example.asynctask.R;public class GridAdapter extends BaseAdapter implements OnScrollListener {private List<MoviesIfo> movies;private Context context;private ViewHolder holder;// 存放全部的URLpublic static String[] urls;private RequestImageByAsyncTask asyncReqImage;public GridAdapter(List<MoviesIfo> movies, Context context,GridView gridView) {// 数据this.movies = movies;this.context = context;    //第二步:初始化asyncReqImage=new RequestImageByAsyncTask(gridView);this.urls = new String[movies.size()];for (int i = 0; i < urls.length; i++) {urls[i] = movies.get(i).getPic();}}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn movies.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn movies.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@SuppressLint("ViewHolder")@Overridepublic View getView(int position, View convertView, ViewGroup parent) {MoviesIfo ifo = movies.get(position);// 加载 布局 并 设置 布局holder = new ViewHolder();convertView = View.inflate(context, R.layout.gridlist_item, null);holder.list_image = (ImageView) convertView.findViewById(R.id.list_image);holder.list_tvname = (TextView) convertView.findViewById(R.id.list_tvname);holder.list_tvtotle = (TextView) convertView.findViewById(R.id.list_tvtotle);// 设置图片holder.list_image.setScaleType(ScaleType.FIT_XY);holder.list_image.setImageResource(R.drawable.tubiao);holder.list_tvname.setText(ifo.getName());holder.list_tvtotle.setText("给力的电影 id= " + ifo.getId());/** * 第一步:给图片设置Tag */holder.list_image.setTag(urls[position]);// ReqeustImageByThread reqeustImage = new// ReqeustImageByThread(ifo.getPic(),// holder.list_image);// reqeustImage.start();//RequestImageByRunnable requestImageByRunnable = new RequestImageByRunnable(//ifo.getPic(), holder.list_image);//requestImageByRunnable.RequestImage();return convertView;}class ViewHolder {public ImageView list_image;public TextView list_tvname, list_tvtotle;}private int start;private int end;    //第一次加载private boolean isFrist=true;@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {// 状态改变// 停止滑动的时候if (SCROLL_STATE_IDLE == scrollState) {// 停止滑动 ,开始加载数据// 如果在 滑动的时候加载数据,可能发生卡顿asyncReqImage.ReqImage(start, end);} else {// 滑动时,取消加载asyncReqImage.Reqcancel();}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// 位置控制start = firstVisibleItem;end = firstVisibleItem + visibleItemCount;/** * 两个条件: * isFrist: 判断第一次加载; * visibleItemCount :可用item的数量 大于0 时 进行第一次加载; */if(isFrist&&visibleItemCount>0){asyncReqImage.ReqImage(start, end);isFrist=false;}}}

6.异步加载

   (1)将异步任务 存放在list中,实现任务的可控性;

   (2)圆角实现:直接将bitmap 转换为圆角 存放在缓存中;

package com.example.Adapter;import java.util.ArrayList;import java.util.List;import android.graphics.Bitmap;import android.os.AsyncTask;import android.widget.GridView;import android.widget.ImageView;import com.example.Http.PictureDraw;import com.example.Http.UrlConnGetdata;import com.example.asynctask.R;public class RequestImageByAsyncTask {/** * AsyncTask 实现异步加载 *  */private GridView gridView;/** * 初始化 基础地址 */private final static String baseUrl = "http://192.168.75.1:8081/GoodsServers/";/** * 存放 所有的异步任务:当滑动的时候,停止加载;当停止滑动的时候,加载数据;为了避免卡顿 */private List<ReqImageAsyncTask> asyncTasks = new ArrayList<RequestImageByAsyncTask.ReqImageAsyncTask>();/** * GridView 初始化 *  * @param gridView */public RequestImageByAsyncTask(GridView gridView) {// 初始化 listview :作用 通过 listview 来 获取 ImageView的值this.gridView = gridView;}/** * 添加加载任务 *  * @param start * @param end */public void ReqImage(int start, int end) {for (int i = start; i < end; i++) {String url = GridAdapter.urls[i];ImageView imageView = (ImageView) gridView.findViewWithTag(url);ReqImageAsyncTask asyncTask = new ReqImageAsyncTask(imageView);asyncTask.execute(baseUrl + url);asyncTasks.add(asyncTask);}}/** * 取消请求任务 *  */public void Reqcancel() {for (ReqImageAsyncTask reqImageAsyncTask : asyncTasks) {if (!reqImageAsyncTask.isCancelled()) {reqImageAsyncTask.cancel(true);}}}/** * 根据路径 获得图片 *  * @param picpath * @return */private Bitmap getBitmap(String picpath) {return UrlConnGetdata.getBitmap(picpath);}/** * 请求图片 异步任务 *  * @author yuan * */class ReqImageAsyncTask extends AsyncTask<String, Void, Bitmap> {private ImageView Img;public ReqImageAsyncTask(ImageView view) {// 初始化this.Img = view;}@Overrideprotected Bitmap doInBackground(String... params) {// 请求图片String ReqUrl = params[0];Bitmap bitmap = null;ImageCache imageCache = ImageCache.getinstance();if (imageCache.isKey(ReqUrl)) {// 如果 存在 ,去内存中的bitmap = imageCache.getCache(ReqUrl);} else {// 否则 ,请求 图片bitmap = getBitmap(ReqUrl);//存到缓存中 ,圆角imageCache.setCache(ReqUrl,PictureDraw.toRoundCorner(bitmap, 10));}return bitmap;}@Overrideprotected void onPostExecute(Bitmap bitmap) {// 得到图片if (bitmap != null) {Img.setImageBitmap(bitmap);} else {Img.setImageResource(R.drawable.fail);}}}}


7.圆角实现

/** *//** * 把图片变成圆角 *  * @param bitmap *            需要修改的图片 * @param pixels *            圆角的弧度 * @return 圆角图片 */public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888);Canvas canvas = new Canvas(output);final int color = 0xff424242;final Paint paint = new Paint();final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());final RectF rectF = new RectF(rect);final float roundPx = pixels;paint.setAntiAlias(true);canvas.drawARGB(0, 0, 0, 0);paint.setColor(color);canvas.drawRoundRect(rectF, roundPx, roundPx, paint);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));canvas.drawBitmap(bitmap, rect, rect, paint);return output;}


8.总结

   在进行列表优化的时候,主要通过 onScroll() 和 onScrollStateChanged() 两个方法来判断,当前页的数据;

   还有获得ImageView 通过 findviewWithTag实现;与之前设置的tag对应;


0 0
原创粉丝点击