0.调用:

  BaseAdapter中设置方法  holder.iv.loadImage(url);

  adapter_xxx.xml 中 控件需要用 xxx.NetWorkImageView

1 NetWorkImageView.java 和 异步加载图片的代码 AsyncImageLoader.java

import com.example.textimage.AsyncImageLoader.ImageLoadCallback;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView; /**
* 自定义加载网络图片ImageView
*
* @author mrljdx
* https://github.com/mrljdx/LoadImageView/tree/master/src/com/mrljdx
* /loadimage
*
*/
public class NetWorkImageView extends ImageView {
private final static String TAG = "NetWorkImageView";
private static AsyncImageLoader asyncImageLoader;
private Context context; public NetWorkImageView(Context context) {
this(context, null);
} public NetWorkImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public NetWorkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initSth(context);
} private void initSth(Context context) {
this.context = context;
if (asyncImageLoader == null) {
asyncImageLoader = new AsyncImageLoader(context);
}
} public void loadImage(String imgUrl, final int defaultRes) {
if (TextUtils.isEmpty(imgUrl)) {
setImageResource(defaultRes);// 调用ImageView中默认的设置图片方法
return;
}
Log.d(TAG, "load imgUrl is :" + imgUrl);
Drawable d = asyncImageLoader.loadDrawable(imgUrl,
new ImageLoadCallback() { @Override
public void imageLoaded(Drawable drawable, String imgUrl) {
Object tag = getTag(); // 获取NetWorkImageView设置的Tag值,比对如果有则不再重新加载
if (tag != null && (tag instanceof String)
&& !tag.toString().equals(imgUrl)) {
return;
}
if (context instanceof Activity) { // 如果当前Activity被结束了,则不加载图片
if (((Activity) context).isFinishing()) {
return;
}
}
// 设置显示图片
setImage(drawable, defaultRes);
}
});
setImage(d, defaultRes);
} // 显示图片
private void setImage(Drawable drawable, int defaultRes) {
if (drawable != null) {
setImageDrawable(drawable);
return;
}
if (defaultRes != -1) {
setImageResource(defaultRes);
} } public void loadImage(String imgUrl) {
loadImage(imgUrl, -1);
} /**
* 取消加载图片
*/
public void cancelTask() {
asyncImageLoader.shutDownTread();
} }
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log; /**
* 异步网络请求图片加载类
*
* @author mrljdx
*
*/
public class AsyncImageLoader {
final static String TAG = "AsyncImageLoader";
/** /sdcard/Android/data/%package_name%/files/images */
private static File PIC_PATH; private static HashMap<String, SoftReference<Drawable>> picCache;
private BitmapFactory.Options opts = new BitmapFactory.Options();
private ExecutorService excutorsService = Executors.newFixedThreadPool(1);
private int width;
private int height;
private Context mContext; public AsyncImageLoader(Context context) {
this.mContext = context;
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
Log.d(TAG, "Max memory is " + maxMemory + "M"); PIC_PATH = new File(mContext.getExternalFilesDir("images")
+ File.separator); picCache = new HashMap<String, SoftReference<Drawable>>();
opts.inSampleSize = 1;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
} public void setThreads(int num) {
this.excutorsService = Executors.newFixedThreadPool(num);
} public interface ImageLoadCallback {
public void imageLoaded(Drawable drawable, String imgUrl);
} // 加载图片
public Drawable loadDrawable(final String imgUrl,
final ImageLoadCallback mCallback) {
if (TextUtils.isEmpty(imgUrl)) {
return null;
}
// 获取图片文件名称
final String fileName = imgUrl.substring(imgUrl.lastIndexOf("/") + 1);
final String imgUrlHashCode = imgUrl.hashCode() + "";
// 如果有缓存则返回图片
if (picCache.containsKey(imgUrlHashCode)) {
Drawable imgDrawable = picCache.get(imgUrlHashCode).get();
if (imgDrawable != null) {
return imgDrawable;
}
}
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
mCallback.imageLoaded((Drawable) msg.obj, imgUrl);
}
};
excutorsService.submit(new Runnable() { @Override
public void run() {
Drawable drawable = loadImageFromUrl(imgUrl, fileName);
if (drawable != null) {// 获取到图片
if (width != 0) {
try {
drawable = zoomDrawable(drawable, width, height,
fileName);
} catch (Exception e) {
e.printStackTrace();
}
width = 0;
height = 0;
}
picCache.put(imgUrlHashCode, new SoftReference<Drawable>(
drawable));
}
handler.sendMessage(handler.obtainMessage(0, drawable));
}
});
return null;
} // 通过网络请求获取图片
public Drawable loadImageFromUrl(String imgUrl, String fileName) {
if (TextUtils.isEmpty(imgUrl)) {
return null;
}
Drawable drawable = null;
fileName = String.valueOf(fileName.hashCode()); // 将文件名hash
if (!PIC_PATH.exists()) {// 判断存放图片的文件夹是否存在
PIC_PATH.mkdirs();// 不存在则创建一个图片文件夹
}
File imgFile = new File(PIC_PATH, fileName);
if (imgFile.exists()) {// 如果存在在SD卡中,则返回SD卡里的图片
try {
drawable = getDrawableFromSdcard(fileName);
} catch (OutOfMemoryError outOfMemoryError) {
outOfMemoryError.printStackTrace();
return null;
}
return getDrawableFromSdcard(fileName);
} else {// 如果内存和SD卡都不存在则网络请求图片
URL url;
BufferedInputStream inputStream = null;
HttpURLConnection con = null;
try {
Log.d(TAG, "load imgUrl is:" + imgUrl);
url = new URL(imgUrl);
con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(15000);// 设置网络请求超时时间15秒
con.setReadTimeout(15000);
con.connect(); InputStream is = con.getInputStream(); // 获取图片流
inputStream = new BufferedInputStream(is); // 赋值
saveImage(imgFile, inputStream); // 保存图片到本地SD卡
is.close();// 关闭输入流 // String imgCookie = con.getHeaderField(pos); } catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (MalformedURLException e1) {
e1.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (con != null) {
con.disconnect();
}
if (inputStream != null)
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} return drawable;
} // 从本地SD卡获取图片
private Drawable getDrawableFromSdcard(String fileName) { Bitmap source = BitmapFactory.decodeFile(PIC_PATH + File.separator
+ fileName, opts);
if (source == null) {
return null;
} else {
return new BitmapDrawable(source);
}
} // 保存图片到本地SD卡
private void saveImage(File image, BufferedInputStream bis) {
if (image != null && image.getParentFile() != null) {
image.getParentFile().mkdirs();
}
FileOutputStream fos = null; // 定义文件输出流
int BUFFER_SIZE = 1024;
byte[] buf = new byte[BUFFER_SIZE];
int size = 0;
try {
fos = new FileOutputStream(image);
while ((size = bis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
;
fos.close();
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} // 取消所有正在执行的任务
public void shutDownTread() {
excutorsService.shutdownNow();
} // 处理图片
private Drawable zoomDrawable(Drawable drawable, int w, int h,
String fileName) {
// 取图片的真实大小
int intrinsicw = drawable.getIntrinsicWidth();
int intrinsich = drawable.getIntrinsicHeight();
// 设置为true,表示解析Bitmap对象,该对象不占内存
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(PIC_PATH + File.separator + fileName, opts); // 设置为false,解析Bitmap对象加入到内存中
opts.inJustDecodeBounds = false;
int width = opts.outWidth;
int height = opts.outHeight;
drawable.setBounds(0, 0, width, height); int minW = Math.min(width, w);
int minH = Math.min(height, h); float scaleWidth = ((float) w / intrinsicw);
float scaleHeight = ((float) h / intrinsich);
Matrix matrix = new Matrix();
if (minW == width && minH == height) {
scaleWidth = scaleHeight = mContext.getResources()
.getDisplayMetrics().density;
} else if (minW == width && minH == h) {
scaleWidth = scaleHeight;
} else if (minW == w && minH == height) {
scaleHeight = scaleWidth;
} else {
scaleWidth = scaleHeight = Math.min(scaleWidth, scaleHeight);
}
Bitmap oldbmp = drawableToBitmap(drawable, width, height);
matrix.postScale(scaleWidth, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,
matrix, true);
return new BitmapDrawable(null, newbmp);
} // Drawable To Bitmap
private Bitmap drawableToBitmap(Drawable drawable, int width, int height) {
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565;
Bitmap bitmap = Bitmap.createBitmap(width, height, config);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
}

android 自定义控件之NetWorkImageView 处理listview等控件中的图片加载乱序问题的更多相关文章

  1. Winform开发框架之客户关系管理系统(CRM)的开发总结系列4-Tab控件页面的动态加载

    在前面介绍的几篇关于CRM系统的开发随笔中,里面都整合了多个页面的功能,包括多文档界面,以及客户相关信息的页面展示,这个模块就是利用DevExpress控件的XtraTabPage控件的动态加载实现的 ...

  2. Android自定义控件View(三)组合控件

    不少人应该见过小米手机系统音量控制UI,一个圆形带动画效果的音量加减UI,效果很好看.它是怎么实现的呢?这篇博客来揭开它的神秘面纱.先上效果图 相信很多人都知道Android自定义控件的三种方式,An ...

  3. 控件WebView网页的加载

    Android:控件WebView网页的加载 WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWe ...

  4. 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图

    [源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...

  5. 在RichTextBox控件中插入图片

    . 在RichTextBox控件中插入图片 关键点 . 实现过程 .   public void ShowInsertImageDlg() {     OpenFileDialog OpenFileD ...

  6. 在RichTextBox控件中添加图片和文字

    public void SetText(RichTextBox rtb) { rtb.Text = "在RichTextBox控件中添加图片和文字" + Environment.N ...

  7. 背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互

    [源码下载] 背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互 作者: ...

  8. Android Handler 异步消息处理机制的妙用 创建强大的图片加载类(转)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 最近创建了一个群,方便大家交流,群号: ...

  9. 一起来学习Android自定义控件2-简单的写字板控件

    概述 上一篇文章我们对自定义控件进行了一个大体的知识介绍.今天就来学习自定义一个简单的写字板控件. 先来看看效果图 就是简单的根据手指写下的轨迹去画出内容 实现 在上一篇文章里提到了android官方 ...

随机推荐

  1. Maven:禁止编码指定类型的资源文件

    [参考文章]:项目编译后dll文件调用出错 maven 在编译或项目时,可能会对资源文件进二次编码(编译前后的文件大小对比即可发现该问题),有些文件(例如:文本文件)可能不会影响我们是用,但是有些文件 ...

  2. Ubuntu下制作deb包的方法详解

    1  认识deb包 1.1   认识deb包 deb是Unix系统(其实主要是Linux)下的安装包,基于 tar 包,因此本身会记录文件的权限(读/写/可执行)以及所有者/用户组. 由于 Unix ...

  3. memcached出现:Fatal error: Call to undefined method Memcached::connect()

    今天安装了memcached的服务端和客户端 装好试了一下 $mem = new Memcached;  $mem -> connect("127.0.0.1",11211) ...

  4. MySQL软件的相关操作

    服务的启动与关闭 * 启动 net start mysql * 关闭 net stop mysql * 打开服务窗口 services.msc *查询端口号: netstat -ano mysql密码 ...

  5. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_23-页面预览-页面预览开发

    1.用户进入cms前端,点击“页面预览”在浏览器请求cms页面预览链接. 2.cms根据页面id查询DataUrl并远程请求DataUrl获取数据模型. 3.cms根据页面id查询页面模板内容 4.c ...

  6. win7上 nginx 出现 403 Forbidden

    一般是目录权限问题,在conf文件找到 location / { index index.html index.htm index.php;# autoindex on; } 把#去掉就可以了.

  7. 使用linux flock文件锁实现任务锁定避免计划任务程序冲突

    格式:flock [-sxun][-w #] fd#flock [-sxon][-w #] file [-c] command选项-s, --shared: 获得一个共享锁 -x, --exclusi ...

  8. FTP与SFTP的区别

    简介 wikipedia - FTP --- FTP File Transfer wikipedia - SFTP --- SSH File Transfer 对比 缩写 名称 协议与端口 安全策略 ...

  9. Django学习参考资料

    0. HTTP协议简介http://www.cnblogs.com/maple-shaw/articles/9060408.html 1. 路由系统https://www.cnblogs.com/ma ...

  10. 最新 龙采科技java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.龙采科技等10家互联网公司的校招Offer,因为某些自身原因最终选择了龙采科技.6.7月主要是做系统复习.项目复盘.Leet ...