现在我们终于可以通过这个框架来实现ListView中加载图片了,至于ViewPager还是别的,原理其实都是一样的

一、ListView

1.布局文件

list_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView> </LinearLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <ImageView
android:id="@+id/item_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" /> </LinearLayout>

图片来源类:

package com.kale.universalimageloadertest;

public class PicArrays {

    public static String[] getPicArray() {

        String[] arrs = new String[]{
"http://static4.photo.sina.com.cn/middle/69670edbx9475f3f01283&690",
"http://s8.sinaimg.cn/middle/6f78405exa6e437719ea7&690",
"http://s3.sinaimg.cn/middle/6f78405ex9f4d66911f22&690",
"http://s8.sinaimg.cn/middle/6f78405exa6e436d8f357&690",
"http://s4.sinaimg.cn/middle/6f78405exa6e43621ecb3&690",
"http://s10.sinaimg.cn/middle/6f78405exa0f4f335c589&690",
"http://s16.sinaimg.cn/middle/6f78405ex9f4d7b2eff0f&690",
"http://s7.sinaimg.cn/middle/6f78405exa6e2fa1d4ab6&690",
"http://s8.sinaimg.cn/middle/6f78405exa6e2fa4b19c7&690",
"http://s6.sinaimg.cn/middle/69670edbx94da12276525&690",
"http://s2.sinaimg.cn/middle/69670edbx94da117f7c41&690",
"http://s3.sinaimg.cn/bmiddle/6f78405exa503c5d0a462&690",
"http://s6.sinaimg.cn/middle/6f78405exa72b24119765&690",
"http://s11.sinaimg.cn/middle/6f78405ex9f4d5245988a&690",
"http://s10.sinaimg.cn/middle/6f78405ex9f4d7b107f29&690",
"http://img0.tech2ipo.com/upload/img/article/2013/03/1364556945327.png",
"http://s7.sinaimg.cn/middle/6f78405eta77a260b8d96&690",
"http://s3.sinaimg.cn/middle/6f78405eta77a29344d92&690",
"http://s10.sinaimg.cn/middle/6f78405exa0f4f250e469&690",
"http://s3.sinaimg.cn/middle/6f78405eta77a21932632&690",
"http://s13.sinaimg.cn/middle/6f78405eta77a2c9a0d2c&690",
"http://s9.sinaimg.cn/middle/6f78405eta77a47b89188&690",
"http://s16.sinaimg.cn/middle/6f78405exa0f4f11fb58f&690",
"http://img2.imgtn.bdimg.com/it/u=2449553173,1966285445&fm=23&gp=0.jpg",
"http://h.hiphotos.baidu.com/baike/w%3D150/sign=406f3d00251f95caa6f596b3f9167fc5/d50735fae6cd7b89493402fd0f2442a7d9330e77.jpg"
};
return arrs;
} public static void main(String[] args) {
System.out.println("图片总数:"+getPicArray().length);
} }

写一个listview的适配器

这里在载入图片的时候放入了一个动画的效果。可见这个框架的扩展性是相当强的!!!

    final private DisplayImageOptions options = getSimpleOptions();
final private ImageLoader imageLoader = ImageLoader.getInstance();
    /**
*
* 自定义列表项适配器
*
*/
class ItemAdapter extends BaseAdapter { //图片第一次加载的监听器
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
private String[] picArrs; public ItemAdapter() {
// TODO 自动生成的构造函数存根
picArrs = PicArrays.getPicArray();
}
private class ViewHolder {
public ImageView image;
} @Override
public int getCount() {
return picArrs.length;
} @Override
public Object getItem(int position) {
return position;
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
//通过convertView来判断是否已经加载过了,如果没有就加载
if (convertView == null) {
view = getLayoutInflater().inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) view.findViewById(R.id.item_imageView);
view.setTag(holder);// 给View添加一个格外的数据
} else {
holder = (ViewHolder) view.getTag(); // 把数据取出来
} /**
* 显示图片
* 参数1:图片url
* 参数2:显示图片的控件
* 参数3:显示图片的设置
* 参数4:监听器
*/
imageLoader.displayImage(picArrs[position], holder.image, options,animateFirstListener); return view;
}
} /**
* 图片加载第一次显示监听器
* @author Administrator
*
*/
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>()); @Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
// 是否第一次显示
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
// 图片淡入效果
FadeInBitmapDisplayer.animate(imageView, 200);
displayedImages.add(imageUri);
}
}
}
}

全部的Activity代码:

package com.kale.universalimageloadertest;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import com.nostra13.universalimageloader.core.listener.PauseOnScrollListener;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; public class UILListActivity extends Activity{ final private DisplayImageOptions options = getSimpleOptions();
final private ImageLoader imageLoader = ImageLoader.getInstance(); @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.list_layout); ListView listView = (ListView)findViewById(R.id.listView);
/*
* 3个参数->
* 1:图片加载对象ImageLoader,
* 2:控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了
* 3:控制猛的滑动界面的时候图片是否加载
*
*/
listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, false, true));
listView.setAdapter(new ItemAdapter()); } /**
* 设置常用的设置项
* @return
*/
private DisplayImageOptions getSimpleOptions() {
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.loading) //设置图片在下载期间显示的图片
.showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.error) //设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)//设置下载的图片是否缓存在内存中
.cacheOnDisk(true)//设置下载的图片是否缓存在SD卡中
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)//设置图片以如何的编码方式显示
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型
.build();//构建完成
return options;
} /**
*
* 自定义列表项适配器
*
*/
class ItemAdapter extends BaseAdapter { //图片第一次加载的监听器
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
private String[] picArrs; public ItemAdapter() {
// TODO 自动生成的构造函数存根
picArrs = PicArrays.getPicArray();
}
private class ViewHolder {
public ImageView image;
} @Override
public int getCount() {
return picArrs.length;
} @Override
public Object getItem(int position) {
return position;
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
//通过convertView来判断是否已经加载过了,如果没有就加载
if (convertView == null) {
view = getLayoutInflater().inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) view.findViewById(R.id.item_imageView);
view.setTag(holder);// 给View添加一个格外的数据
} else {
holder = (ViewHolder) view.getTag(); // 把数据取出来
} /**
* 显示图片
* 参数1:图片url
* 参数2:显示图片的控件
* 参数3:显示图片的设置
* 参数4:监听器
*/
imageLoader.displayImage(picArrs[position], holder.image, options,animateFirstListener); return view;
}
} /**
* 图片加载第一次显示监听器
* @author Administrator
*
*/
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>()); @Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
// 是否第一次显示
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
// 图片淡入效果
FadeInBitmapDisplayer.animate(imageView, 200);
displayedImages.add(imageUri);
}
}
}
}
}

通过ViewHolder和convertView配合使用,可以提高效率。这点也是我们应该学习的

二、ViewPager

viewPager_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

viewpager_item.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="1dip"> <ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:contentDescription="@string/hello_world" /> <ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" /> </FrameLayout>

UILViewPagerActivity.java

package com.kale.universalimageloadertest;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; public class UILViewPagerActivity extends Activity { ViewPager pager;
DisplayImageOptions options;
ImageLoader imageLoader; private static final String STATE_POSITION = "STATE_POSITION"; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_layout); // 当前显示View的位置
*/
int pagerPosition = 0; // 如果之前有保存用户数据
if (savedInstanceState != null) {
pagerPosition = savedInstanceState.getInt(STATE_POSITION);
} options = getSimpleOptions();
imageLoader = ImageLoader.getInstance(); pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(new ImagePagerAdapter(PicArrays.getPicArray()));
pager.setCurrentItem(pagerPosition);
} @Override
public void onSaveInstanceState(Bundle outState) {
//
outState.putInt(STATE_POSITION, pager.getCurrentItem());
} /**
* 设置常用的设置项
*
* @return
*/
private DisplayImageOptions getSimpleOptions() {
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.loading) // 设置图片在下载期间显示的图片
.showImageForEmptyUri(R.drawable.ic_launcher)// 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.error) // 设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)// 设置下载的图片是否缓存在内存中
.cacheOnDisk(true)// 设置下载的图片是否缓存在SD卡中
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)// 设置图片以如何的编码方式显示
.considerExifParams(true).bitmapConfig(Bitmap.Config.RGB_565)// 设置图片的解码类型
.build();// 构建完成
return options;
} private class ImagePagerAdapter extends PagerAdapter { private String[] images;
private LayoutInflater inflater; ImagePagerAdapter(String[] images) {
this.images = images;
inflater = getLayoutInflater();
} @Override
public int getCount() {
return images.length;
} @Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
} @Override
public Object instantiateItem(ViewGroup view, int position) {
View viewLayout = inflater.inflate(R.layout.viewpager_item, view,
false);
ImageView imageView = (ImageView) viewLayout
.findViewById(R.id.image);
final ProgressBar spinner = (ProgressBar) viewLayout
.findViewById(R.id.loading); imageLoader.displayImage(images[position], imageView, options,
new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
spinner.setVisibility(View.VISIBLE);
} @Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
String message = null;
switch (failReason.getType()) { // 获取图片失败类型
case IO_ERROR: // 文件I/O错误
message = "Input/Output error";
break;
case DECODING_ERROR: // 解码错误
message = "Image can't be decoded";
break;
case NETWORK_DENIED: // 网络延迟
message = "Downloads are denied";
break;
case OUT_OF_MEMORY: // 内存不足
message = "Out Of Memory error";
break;
case UNKNOWN: // 原因不明
message = "Unknown error";
break;
}
Toast.makeText(getApplicationContext(), message,
Toast.LENGTH_SHORT).show(); spinner.setVisibility(View.GONE);
} @Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE); // 不显示圆形进度条
}
}); ((ViewPager) view).addView(viewLayout, 0); // 将图片增加到ViewPager
return viewLayout;
} @Override
public void finishUpdate(View container) {
} } }

这里ViewPager的实现是通过动态加载的方式来做的,结合了进度条。很具有实用性!以前我们用ViewPager的时候是传入一个List<View>对象,在getView()中返回list.getindex(position)的方式来得到view对象。这里不传入view,直接在getView()中产生一个view,然后给view中加载图片。这种方式好处是节约了内存,要显示的时候才判断加载哪个对象;而坏处是没实现预加载,所以要配合进度条。在今后的改进中应该是预加载当前viewpager左右的图片,这样可以流畅的显示图片了~

源码下载:http://download.csdn.net/detail/shark0017/8055421

参考自:

http://blog.csdn.net/wwj_748/article/details/10079311

Universal-Image-Loader解析(三)——用ListView和ViewPager加载网络中的图片的更多相关文章

  1. Android基本控件之listView(三)<用ListView实现分页加载>

    我们之前讨论了ListView的基本使用方法和ListView的优化 今天我们再来讨论一个关于ListView的一个新的东西~就是分页加载.那么什么是分页加载呢?简单点说,就是"下拉刷新&q ...

  2. [Android] Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.LoaderCallbacks)

    Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.Lo ...

  3. Python3从零开始爬取今日头条的新闻【三、滚动到底自动加载】

    Python3从零开始爬取今日头条的新闻[一.开发环境搭建] Python3从零开始爬取今日头条的新闻[二.首页热点新闻抓取] Python3从零开始爬取今日头条的新闻[三.滚动到底自动加载] Pyt ...

  4. listView的异步加载数据

    1 public class MainActivity extends Activity { 2 3 private ListView listView; 4 private ArrayList< ...

  5. Flutter 开发从 0 到 1(四)ListView 下拉加载和加载更多

    在<APP 开发从 0 到 1(三)布局与 ListView>我们完成了 ListView,这篇文章将做 ListView 下拉加载和加载更多. ListView 下拉加载 Flutter ...

  6. springboot源码解析-管中窥豹系列之BeanDefine如何加载(十三)

    一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...

  7. ListView用法及加载数据时的闪烁问题和加载数据过慢问题

    ListView介绍及添加数据时的闪烁问题 1.     ListView类 1.1 ListView常用的基本属性: (1)FullRowSelect:设置是否行选择模式.(默认为false) 提示 ...

  8. ListView 上拉加载更多

    ListView 上拉加载更多 首先来个效果图 界面布局 <?xml version="1.0" encoding="utf-8"?> <Re ...

  9. XE7 & FMX 那些年我们一起上过的控件:ListView 之 (3) 加载数据时如何显示自定义样式

    本文介绍一下ListView下如何加载数据.及使用进度条反馈当前进度给用户. 注意: 原创作品,请尊重作者劳动成果,转载请注明出处!!!原文永久固定地址:http://www.cnblogs.com/ ...

随机推荐

  1. zookeeper集群自动启动脚本

    定义脚本boot.sh启动zookeeper集群(hadoop1,hadoop2,hadoop3) #!/bin/bash echo "start zkServer..." do ...

  2. 有多少种JVM

    https://en.wikipedia.org/wiki/Comparison_of_Java_virtual_machines 在这个类别下,主流选择有:(按流行程度递减) HotSpot VM ...

  3. GBDT算法

    GBDT通过多轮迭代,每轮迭代产生一个弱分类器,其中弱分类器通常选择为CART树,每个分类器在上一轮分类器的残差基础上进行训练. 对于GBDT算法,其中重要的知识点为: 1.GBDT是梯度下降法从参数 ...

  4. bzoj 4000 矩阵快速幂优化DP

    建立矩阵,跑快速幂 /************************************************************** Problem: 4000 User: idy002 ...

  5. JAVA初学练手项目,学生管理系统

    github地址:https://github.com/qscqesze/StudentManager 简单描述一下: UI层面用于接受用户的处理信息,然后移交给StudentDao去处理数据. 其中 ...

  6. Codeforces Round #272 (Div. 2) B. Dreamoon and WiFi dp

    B. Dreamoon and WiFi 题目连接: http://www.codeforces.com/contest/476/problem/B Description Dreamoon is s ...

  7. Educational Codeforces Round 14 D. Swaps in Permutation 并查集

    D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...

  8. 接口开发-集成数据库操作(mybatis)

    关于数据存储,最常用的方式就是存到数据库,此篇以MySQL数据库为例,以mybatis框架完成数据库的操作. 一.添加对应依赖 <!-- 数据库:MySQL --> <depende ...

  9. Ubuntu · Docker —— 从入门到实践

      https://yeasy.gitbooks.io/docker_practice/appendix/repo/ubuntu.html#1604-%E7%89%88%E6%9C%AC

  10. What is OpenOCD?

    About OpenOCD was created by Dominic Rath as part of a 2005 diploma thesis written at the University ...