Universal-Image-Loader解析(三)——用ListView和ViewPager加载网络中的图片

       

  现在我们终于可以通过这个框架来实现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

原文地址:https://www.cnblogs.com/tianzhijiexian/p/4034386.html