ImageLoader.java
public class ImageLoader {
private Context context;
private LruCache<Integer, Bitmap> lruCache;//采用Lru算法进行缓存
private Set<MyImageAsyncTask> tasks;//异步任务集合
private ListView listView;
private int[] myRes;//图片资源id数组集合
public ImageLoader(Context context, ListView listView, int[] resid) {
this.context = context;
this.listView = listView;
tasks = new HashSet<>();
myRes = resid;
int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取最大可用内存
int cacheSize = maxMemory / 4;
lruCache = new LruCache<Integer, Bitmap>(cacheSize) {
@Override
protected int sizeOf(Integer key, Bitmap value) {//关键方法具体作用自行查阅相关api
//在每次存入缓存时调用
return value.getByteCount();
}
};
}
//增加到缓存
public void addBitmapToCache(int id, Bitmap bitmap) {
//判断缓存是否存在
if (getBitmapFromCache(id) == null) {
lruCache.put(id, bitmap);
}
}
//从缓存中获取
public Bitmap getBitmapFromCache(int id) {
return lruCache.get(id);
}
public void showImageByAsnycTask(ImageView imageView, int id) {
//从缓存中取出图片
Bitmap bitmap = getBitmapFromCache(id);
if (bitmap == null) {
//若缓存中没有则从资源文件中获取
imageView.setImageResource(0);
} else {
imageView.setImageBitmap(bitmap);
}
}
//根据id获得Bitmap
public Bitmap getBitmapFromId(int Resid) {
Bitmap bitmap;
bitmap = BitmapFactory.decodeResource(context.getResources(), Resid);
return bitmap;
}
//取消所有异步工作
public void cancelAllTasks() {
if (tasks != null) {
for (MyImageAsyncTask task : tasks) {
task.cancel(false);
}
}
}
//用来加载start到end的所有图片,只加载屏幕内所有item的图片(优化作用)
public void loadImages(int start, int end) {
for (int i = start; i < end; i++) {
int resId = myRes[i];
Bitmap bitmap = getBitmapFromCache(resId);
if (bitmap == null) {
//若缓存中没有则去资源中获取
MyImageAsyncTask myAsyncTask = new MyImageAsyncTask(resId);
myAsyncTask.execute(resId);
tasks.add(myAsyncTask);
} else {
//缓存中存在则直接设置
ImageView imageView = (ImageView) listView.findViewWithTag(resId);
imageView.setImageBitmap(bitmap);
}
}
}
private class MyImageAsyncTask extends AsyncTask<Integer, Void, Bitmap> {
int mResId;
public MyImageAsyncTask(int resid) {
this.mResId = resid;
}
@Override
protected Bitmap doInBackground(Integer... params) {
Bitmap bitmap = getBitmapFromId(params[0]);
if (bitmap != null) {
//添加到缓存
addBitmapToCache(params[0], bitmap);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
ImageView imageView = (ImageView) listView.findViewWithTag(mResId);
if (imageView != null && bitmap != null) {
imageView.setImageBitmap(bitmap);
}
tasks.remove(this);//任务集合移除该任务
}
}
}
MyCourseAdapter.java
public class MyCourseAdapter extends CommonAdapter<Course> implements AbsListView.OnScrollListener {
private ImageLoader imageLoader;
private int start, end;
public static int[] IMAGE_RES_IDS;//保存所有图片的资源地址
private boolean firstFlag;//首次加载
public MyCourseAdapter(Context context, List<Course> lists, int layoutId, ListView listView) {
super(context, lists, layoutId);
IMAGE_RES_IDS = new int[lists.size()];
firstFlag = true;
for (int i = 0; i < lists.size(); i++) {
IMAGE_RES_IDS[i] = lists.get(i).getPic();
}
imageLoader = new ImageLoader(context, listView,IMAGE_RES_IDS);
listView.setOnScrollListener(this);
}
@Override
public void convert(ViewHolder viewHolder, Course course) {
viewHolder.setText(R.id.tvTitle, course.getTitle())
.setText(R.id.tvAuthor, course.getAuthor())
.setText(R.id.tvTime, course.getTime())
.setTag(R.id.ivPic, course.getPic());//设置tag让图片与item显示内容不会错位
imageLoader.showImageByAsnycTask((ImageView) viewHolder.getView(R.id.ivPic), course.getPic());//启动异步任务
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
//当前状态处于停止状态,加载可见项
imageLoader.loadImages(start, end);
} else {
//停止所有加载任务
imageLoader.cancelAllTasks();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
start = firstVisibleItem;
end = start + visibleItemCount;
//判断是否首次加载
if (firstFlag == true && visibleItemCount > 0) {
imageLoader.loadImages(start, end);
firstFlag = false;
}
}
}
public class CourseFragment extends Fragment {
private ImageView ivLeft, ivRight;//前进,后退按钮
private TextView tvTitle;//标题
private View view;//用于显示的view
private ListView lvMain;
private List<Course> list;
private MyCourseAdapter myCourseAdapter;
private Intent intent;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.course_fragment, null);
initView();
initData();
initEvent();
initAdapter();
return view;
}
private void initView() {
ivLeft = (ImageView) view.findViewById(R.id.ivLeft);
ivRight = (ImageView) view.findViewById(R.id.ivRight);
tvTitle = (TextView) view.findViewById(R.id.tvTtile);
lvMain = (ListView) view.findViewById(R.id.lvMain);
list = new ArrayList<Course>();
}
private void initData() {
<span style="white-space:pre"> </span>//测试数据,实际开发从数据库或者网络中导出
Course course = new Course(R.drawable.s1, "现代大学教育", "作者:test1", "时间:2016/7/21");
list.add(course);
course = new Course(R.drawable.s2, "数据管理与信息安全", "作者:test2", "时间:2016/7/21");
list.add(course);
myCourseAdapter = new MyCourseAdapter(getActivity(), list, R.layout.course_listview_item, lvMain);
tvTitle.setText("你们好");
ivLeft.setImageResource(R.drawable.list);
ivRight.setImageResource(R.drawable.search);
}
private void initEvent() {
ivLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(getActivity(), AllCourseActivity.class);
startActivity(intent);
}
});
ivRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(getActivity(), SearchActivity.class);
startActivity(intent);
}
});
}
private void initAdapter() {
lvMain.setAdapter(myCourseAdapter);
}
}
自此带图片缓存的通用BaseAdapter结束了,其中用到的相应布局文具,自行测试,祝好运