Android(安卓)实现ListView异步加载图片
16lz
2021-01-26
ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码:
Java代码- package cn.wangmeng.test;
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.ref.SoftReference;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.util.HashMap;
- import android.graphics.drawable.Drawable;
- import android.os.Handler;
- import android.os.Message;
- public class AsyncImageLoader{
- private HashMap<String,SoftReference<Drawable>>imageCache;
- public AsyncImageLoader(){
- imageCache=new HashMap<String,SoftReference<Drawable>>();
- }
- public DrawableloadDrawable( final StringimageUrl, final ImageCallbackimageCallback){
- if (imageCache.containsKey(imageUrl)){
- SoftReference<Drawable>softReference=imageCache.get(imageUrl);
- Drawabledrawable=softReference.get();
- if (drawable!= null ){
- return drawable;
- }
- }
- final Handlerhandler= new Handler(){
- public void handleMessage(Messagemessage){
- imageCallback.imageLoaded((Drawable)message.obj,imageUrl);
- }
- };
- new Thread(){
- @Override
- public void run(){
- Drawabledrawable=loadImageFromUrl(imageUrl);
- imageCache.put(imageUrl,new SoftReference<Drawable>(drawable));
- Messagemessage=handler.obtainMessage(0 ,drawable);
- handler.sendMessage(message);
- }
- }.start();
- return null ;
- }
- public static DrawableloadImageFromUrl(Stringurl){
- URLm;
- InputStreami=null ;
- try {
- m=new URL(url);
- i=(InputStream)m.getContent();
- }catch (MalformedURLExceptione1){
- e1.printStackTrace();
- }catch (IOExceptione){
- e.printStackTrace();
- }
- Drawabled=Drawable.createFromStream(i,"src" );
- return d;
- }
- public interface ImageCallback{
- public void imageLoaded(DrawableimageDrawable,StringimageUrl);
- }
- }
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。
几个辅助类文件:
- package cn.wangmeng.test;
- public class ImageAndText{
- private StringimageUrl;
- private Stringtext;
- public ImageAndText(StringimageUrl,Stringtext){
- this .imageUrl=imageUrl;
- this .text=text;
- }
- public StringgetImageUrl(){
- return imageUrl;
- }
- public StringgetText(){
- return text;
- }
- }
- package cn.wangmeng.test;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.TextView;
- public class ViewCache{
- private ViewbaseView;
- private TextViewtextView;
- private ImageViewimageView;
- public ViewCache(ViewbaseView){
- this .baseView=baseView;
- }
- public TextViewgetTextView(){
- if (textView== null ){
- textView=(TextView)baseView.findViewById(R.id.text);
- }
- return textView;
- }
- public ImageViewgetImageView(){
- if (imageView== null ){
- imageView=(ImageView)baseView.findViewById(R.id.image);
- }
- return imageView;
- }
- }
ViewCache是辅助获取adapter的子元素布局
Java代码- package cn.wangmeng.test;
- import java.util.List;
- import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
- import android.app.Activity;
- import android.graphics.drawable.Drawable;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ArrayAdapter;
- import android.widget.ImageView;
- import android.widget.ListView;
- import android.widget.TextView;
- public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText>{
- private ListViewlistView;
- private AsyncImageLoaderasyncImageLoader;
- public ImageAndTextListAdapter(Activityactivity,List<ImageAndText>imageAndTexts,ListViewlistView){
- super (activity, 0 ,imageAndTexts);
- this .listView=listView;
- asyncImageLoader=new AsyncImageLoader();
- }
- public ViewgetView( int position,ViewconvertView,ViewGroupparent){
- Activityactivity=(Activity)getContext();
- //InflatetheviewsfromXML
- ViewrowView=convertView;
- ViewCacheviewCache;
- if (rowView== null ){
- LayoutInflaterinflater=activity.getLayoutInflater();
- rowView=inflater.inflate(R.layout.image_and_text_row,null );
- viewCache=new ViewCache(rowView);
- rowView.setTag(viewCache);
- }else {
- viewCache=(ViewCache)rowView.getTag();
- }
- ImageAndTextimageAndText=getItem(position);
- //LoadtheimageandsetitontheImageView
- StringimageUrl=imageAndText.getImageUrl();
- ImageViewimageView=viewCache.getImageView();
- imageView.setTag(imageUrl);
- DrawablecachedImage=asyncImageLoader.loadDrawable(imageUrl,new ImageCallback(){
- public void imageLoaded(DrawableimageDrawable,StringimageUrl){
- ImageViewimageViewByTag=(ImageView)listView.findViewWithTag(imageUrl);
- if (imageViewByTag!= null ){
- imageViewByTag.setImageDrawable(imageDrawable);
- }
- }
- });
- if (cachedImage== null ){
- imageView.setImageResource(R.drawable.default_image);
- }else {
- imageView.setImageDrawable(cachedImage);
- }
- //SetthetextontheTextView
- TextViewtextView=viewCache.getTextView();
- textView.setText(imageAndText.getText());
- return rowView;
- }
- }
ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是 imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应 item,大家仔细阅读就知道了。
最后贴出布局文件:
- <?xmlversion= "1.0" encoding= "utf-8" ?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" >
- <ImageViewandroid:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <TextViewandroid:id="@+id/text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>
更多相关文章
- [ZZ][Android]使用bindService启动服务
- Android(安卓)N调用系统安装APK方法报错原因整理及解决方案
- 一个侧屏滑动操作的实例(仿遇见)之三:代码分析
- Android(安卓)多次点击事件的触发方法
- Android(安卓)Geofence的学习(二)继续翻译官方文档
- Android(安卓)结束进程的方法
- Android系统开发之七:添加Android(安卓)Native Service方法
- 2014.03.07 ——— android GridView 记录和恢复位置
- Android(安卓)ApiDemos示例解析(9):App->Activity->Persistent St