zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    借助NetFlow Analyzer的IPAM SPM插件,轻松实现IP和交换机端口管理
    补丁日微软修复了129个漏洞,学习补丁管理最佳实践
    如何通过组策略映射驱动器?
    如何预防磁盘使用率过高?
    ITIL是什么意思?
    Applications Manager—打造最佳云监控策略
    Microsoft 365独家安全解决方案
    怎么让Chrome支持小于12px 的文字?
    vue Router的使用
    vue项目中随机生成验证码
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/4034386.html
Copyright © 2011-2022 走看看