ImageLoader异步加载图片

这段时间在思考技术的价值,可能自己水平太菜吧!没有得出任何结论。

好了废话不说了今天来学习一个开源库ImageLoader异步加载图片

水平有限不敢说深谈,写这篇文章一是分享一下自己的理解,二是巩固知识,三希望更上一层楼


一 简介:

ImageLoader是比较早的异步开源框架了,国内使用的人蛮多的,网上教程很丰富。

ImageLoader的全称是Android-Universal-Image-Loader,在GetHub上可以下载该框架https://github.com/nostra13/Android-Universal-Image-Loader

下面我们来看看ImageLoader的特点:

1.多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等

2.支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存池,硬盘缓存策略等

3.支持图片的内存缓存,文件系统缓存或者SD卡

4.支持图片下载过程的监听

5.根据控件(ImageView)的大小对Bitmap进行裁剪,减小Bitmap占用过多的内存

6.较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用ListView、GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片

7.提供在较慢的网络下对图片进行加载

上面说的还是太抽象了,接下来我们来看一下官方的Demo吧,从官方的Demo入手或许会有惊喜吧

8.android 1.5以上支持


二   ImageLoader 配置

我们来看看官方Demo吧,我觉得看大神Demo是很有益的。
 
1.ImageLoader Application配置
 
/*******************************************************************************
 * Copyright 2011-2013 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample;

import android.annotation.TargetApi;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.os.StrictMode;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class UILApplication extends Application {

	/**
	 * TargetApi:使得高版本的Api在底版中不会报错
	 *
	 * Build.VERSION_CODES.GINGERBREAD:系统的版本号9
	 */
	@TargetApi(Build.VERSION_CODES.GINGERBREAD)
	@SuppressWarnings("unused")
	@Override
	public void onCreate() {
		/**
		 * 当版本号大于9时用严苛模式
		 *
		 * 因为严苛模式只有版本号大于9是才支持
		 */
		if (Constants.Config.DEVELOPER_MODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
			StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyDialog().build());
			StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build());
		}

		super.onCreate();

		/**
		 * ImageLoader的配置参数
		 */
		initImageLoader(getApplicationContext());
	}

	/**
	 * ImageLoader的配置参数
	 */
	public static void initImageLoader(Context context) {
		// This configuration tuning is custom. You can tune every option, you may tune some of them,
		// or you can create default configuration by
		//  ImageLoaderConfiguration.createDefault(this);
		// method.
		ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
		config.threadPriority(Thread.NORM_PRIORITY - 2);
		config.denyCacheImageMultipleSizesInMemory();
		config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
		config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
		config.tasksProcessingOrder(QueueProcessingType.LIFO);
		config.writeDebugLogs(); // Remove for release app

		// Initialize ImageLoader with configuration.
		ImageLoader.getInstance().init(config.build());
	}
}


initImageLoader中是配置参数,在实际开发中根据项目情况可以增加也可以减少

下面是我修改后的代码

/*******************************************************************************
 * Copyright 2011-2013 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample;

import android.annotation.TargetApi;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.os.StrictMode;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.decode.BaseImageDecoder;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.utils.StorageUtils;

import java.io.File;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class UILApplication extends Application {

    /**
     * TargetApi:使得高版本的Api在底版中不会报错
     * <p>
     * Build.VERSION_CODES.GINGERBREAD:系统的版本号9
     */
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    @SuppressWarnings("unused")
    @Override
    public void onCreate() {
        /**
         * 当版本号大于9时用严苛模
         */
        if (Constants.Config.DEVELOPER_MODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyDialog().build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build());
        }

        super.onCreate();

        /**
         * ImageLoader的配置参数
         */
        initImageLoader(getApplicationContext());
    }

    /**
     * ImageLoader的配置参数
     */
    public static void initImageLoader(Context context) {
        // This configuration tuning is custom. You can tune every option, you may tune some of them,
        // or you can create default configuration by
        //  ImageLoaderConfiguration.createDefault(this);
        // method.
        File cacheDir = StorageUtils.getCacheDirectory(context);//返回应用程序缓存目录。缓存目录将在SD卡上创建
        ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);//图片加载器ImageLoader的配置差数
        config.threadPriority(Thread.NORM_PRIORITY - 2);//设置单前线程的优先级
        config.denyCacheImageMultipleSizesInMemory();//缓存显示不同大小的一张图
        config.diskCacheFileNameGenerator(new Md5FileNameGenerator());//将保存的时候的URL名称用MD5加密
        config.diskCacheSize(50 * 1024 * 1024); // // 50 Mb sd卡(本地)缓存的最大值
        config.tasksProcessingOrder(QueueProcessingType.LIFO);//先进先出
        config.writeDebugLogs(); // Remove for release app 打印debug log
        /**
         * 新增的
         */
        config.threadPoolSize(3); //线程池内加载的数量
        config.memoryCacheExtraOptions(480, 800); // max width, max height,即保存的每个缓存文件的最大长宽
        config.diskCacheExtraOptions(480, 800, null); // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个
        config.memoryCacheSize(2 * 1024 * 1024);  // 内存缓存的最大值
        config.memoryCacheSizePercentage(13); // 设置最大的缓存大小
        config.diskCache(new UnlimitedDiskCache(cacheDir)); // default 为图像设置磁盘缓存
        config.diskCacheSize(50 * 1024 * 1024);//为图像设置最大的磁盘缓存大小(以字节为单位)。
        config.diskCacheFileCount(100);// 可以缓存的文件数量
        config.diskCacheFileNameGenerator(new HashCodeFileNameGenerator());// 为在磁盘缓存中缓存的文件设置名称生成器
        config.imageDownloader(new BaseImageDownloader(context)); // default 下载图片
        config.defaultDisplayImageOptions(DisplayImageOptions.createSimple());// default图像选项
        config.imageDownloader(new BaseImageDownloader(context,5 * 1000, 30 * 1000)); // connectTimeout (5 s), readTimeout (30 s)超时时间
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config.build());//全局初始化此配置
    }
}


2.主页(进入的第一个页面HomeActivity.class)


接下来我们看看主页,我已经做了注解


/*******************************************************************************
 * Copyright 2011-2013 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;
import com.nostra13.universalimageloader.sample.fragment.ImageGalleryFragment;
import com.nostra13.universalimageloader.sample.fragment.ImageGridFragment;
import com.nostra13.universalimageloader.sample.fragment.ImageListFragment;
import com.nostra13.universalimageloader.sample.fragment.ImagePagerFragment;
import com.nostra13.universalimageloader.utils.L;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class HomeActivity extends Activity {

	private static final String TEST_FILE_NAME = "Universal Image Loader @#&=+-_.,!()~'%20.png";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.ac_home);

		File testImageOnSdCard = new File("/mnt/sdcard", TEST_FILE_NAME);
		/**
		 * 判断路径是否存在
		 */
		if (!testImageOnSdCard.exists()) {
			copyTestImageToSdCard(testImageOnSdCard);
		}
	}

	/**
	 * ListView
	 * @param view
	 */
	public void onImageListClick(View view) {
		Intent intent = new Intent(this, SimpleImageActivity.class);
		intent.putExtra(Constants.Extra.FRAGMENT_INDEX, ImageListFragment.INDEX);
		startActivity(intent);
	}

	/**
	 * GridView
	 * @param view
	 */
	public void onImageGridClick(View view) {
		Intent intent = new Intent(this, SimpleImageActivity.class);
		intent.putExtra(Constants.Extra.FRAGMENT_INDEX, ImageGridFragment.INDEX);
		startActivity(intent);
	}


	/**
	 * ViewPager
	 * @param view
	 */
	public void onImagePagerClick(View view) {
		Intent intent = new Intent(this, SimpleImageActivity.class);
		intent.putExtra(Constants.Extra.FRAGMENT_INDEX, ImagePagerFragment.INDEX);
		startActivity(intent);
	}

	/**
	 * gallery 画廊
	 * @param view
	 */
	public void onImageGalleryClick(View view) {
		Intent intent = new Intent(this, SimpleImageActivity.class);
		intent.putExtra(Constants.Extra.FRAGMENT_INDEX, ImageGalleryFragment.INDEX);
		startActivity(intent);
	}

	/**
	 * ViewPager (ListView + GridView)
	 * @param view
	 */
	public void onFragmentsClick(View view) {
		Intent intent = new Intent(this, ComplexImageActivity.class);
		startActivity(intent);
	}

	/**
	 * 按后退建是停止加载
	 */
	@Override
	public void onBackPressed() {
		ImageLoader.getInstance().stop();
		super.onBackPressed();
	}

	/**
	 * 显示菜单
	 * @param menu
	 * @return
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.item_clear_memory_cache:
				//清除内存缓存
				ImageLoader.getInstance().clearMemoryCache();
				return true;
			case R.id.item_clear_disc_cache:
				/**
				 * 清除磁盘缓存
				 */
				ImageLoader.getInstance().clearDiskCache();
				return true;
			default:
				return false;
		}
	}

	/**
	 * 把文件拷贝到SD卡
	 * @param testImageOnSdCard
	 */
	private void copyTestImageToSdCard(final File testImageOnSdCard) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					/**
					 *  assets文件夹里面的文件都是保持原始的文件格式,需要用AssetManager以字节流的形式读取文件。
					 先在Activity里面调用getAssets() 来获取AssetManager引用。
					 再用AssetManager的open(String fileName, int accessMode) 方法则指定读取的文件以及访问模式就能得到输入流InputStream。
					 */
					InputStream is = getAssets().open(TEST_FILE_NAME);
					//FileOutputStream:创建一个向指定File对象表示的文件中写入数据的文件输出流
					FileOutputStream fos = new FileOutputStream(testImageOnSdCard);
					byte[] buffer = new byte[8192];
					int read;
					try {
						while ((read = is.read(buffer)) != -1) {
							/**
							 * 写入文件
							 */
							fos.write(buffer, 0, read);
						}
					} finally {
						/**
						 * 主要用在IO中,即清空缓冲区数据,一般在读写流(stream)的时候,数据是先被读到了内存中,再把数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,
						 * 因为还有一部分有可能会留在内存这个缓冲区中。这时候如果你调用了close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先flush()。
						 */
						fos.flush();
						fos.close();
						is.close();
					}
				} catch (IOException e) {
					L.w("Can't copy test image onto SD card");
				}
			}
		}).start();
	}
}

来张主页截图


 

3.来看看SimpleImageActivity.class

HomeActivity会传过来一个值,根据这个值判断显示哪个Fragment

/*******************************************************************************
 * Copyright 2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.activity;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;
import com.nostra13.universalimageloader.sample.fragment.ImageGalleryFragment;
import com.nostra13.universalimageloader.sample.fragment.ImageGridFragment;
import com.nostra13.universalimageloader.sample.fragment.ImageListFragment;
import com.nostra13.universalimageloader.sample.fragment.ImagePagerFragment;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class SimpleImageActivity extends FragmentActivity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		/**
		 * 获取传过来的值
		 *
		 */
		int frIndex = getIntent().getIntExtra(Constants.Extra.FRAGMENT_INDEX, 0);
		Fragment fr;
		String tag;
		int titleRes;
		switch (frIndex) {
			default:
				/**
				 * ListView
				 */
			case ImageListFragment.INDEX:
				/**
				 * Class.getSimpleName()方法。是获取源代码中给出的‘底层类’简称
				 *
				 *这里把Fragment标记设为了‘底层类的’简称
				 */
				tag = ImageListFragment.class.getSimpleName();

				/**
				 * getSupportFragmentManager()获取FragmentManager()
				 *
				 *findFragmentByTag://根据TAG找到对应的Fragment实例,主要用于在动态添加的fragment中,根据TAG来找到fragment实例  
				 */
				fr = getSupportFragmentManager().findFragmentByTag(tag);
				if (fr == null) {
					fr = new ImageListFragment();
				}
				titleRes = R.string.ac_name_image_list;
				break;
			/**
			 * GridView
			 */
			case ImageGridFragment.INDEX:
				tag = ImageGridFragment.class.getSimpleName();
				fr = getSupportFragmentManager().findFragmentByTag(tag);
				if (fr == null) {
					fr = new ImageGridFragment();
				}
				titleRes = R.string.ac_name_image_grid;
				break;
			/**
			 * ViewPager
			 */
			case ImagePagerFragment.INDEX:
				tag = ImagePagerFragment.class.getSimpleName();
				/**
				 * getSupportFragmentManager:
				 *
				 */

				fr = getSupportFragmentManager().findFragmentByTag(tag);
				if (fr == null) {
					fr = new ImagePagerFragment();
					fr.setArguments(getIntent().getExtras());
				}
				titleRes = R.string.ac_name_image_pager;
				break;
			/**
			 * gallery 画廊
			 */
			case ImageGalleryFragment.INDEX:
				tag = ImageGalleryFragment.class.getSimpleName();
				fr = getSupportFragmentManager().findFragmentByTag(tag);
				if (fr == null) {
					fr = new ImageGalleryFragment();
				}
				titleRes = R.string.ac_name_image_gallery;
				break;
		}
		/**
		 * 设置标题内容
		 */
		setTitle(titleRes);
		/**
		 *使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
		 */
		getSupportFragmentManager().beginTransaction().replace(android.R.id.content, fr, tag).commit();
	}
}

4.来看看Fragment的2个基类


进入SimpleImageActivity界面我们可以看到有4个Fragment界面

好了重点来了

我们这四个Fragment都继承了AbsListViewBaseFragment这个Fragment类,AbsListViewBaseFragment这个类继承自BaseFragment


先来看看BaseFragment吧,这个类非常简单来看看源码


/*******************************************************************************
 * Copyright 2011-2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.sample.R;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public abstract class BaseFragment extends Fragment {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);


		/**
		 * 通过onCreateOptionsMenu(),fragment可以为activity的Options Menu提供菜单项。为了确保这一方法成功实现回调。必须在onCreate()期间调用setHasOptionsMenu()告知Options Menu fragment要添加菜单项。
		 */
		setHasOptionsMenu(true);
	}
	/**
	 * 通过onCreateOptionsMenu(),fragment可以为activity的Options Menu提供菜单项。为了确保这一方法成功实现回调。必须在onCreate()期间调用setHasOptionsMenu()告知Options Menu fragment要添加菜单项。
	 */
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		inflater.inflate(R.menu.main_menu, menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			/**
			 * 清除内存缓存
			 */
			case R.id.item_clear_memory_cache:
				ImageLoader.getInstance().clearMemoryCache();
				return true;
			/**
			 * 清除磁盘缓存
			 */
			case R.id.item_clear_disc_cache:
				ImageLoader.getInstance().clearDiskCache();
				return true;
			default:
				return false;
		}
	}
}


接下来是AbsListViewBaseFragment这个类代码多一点,来上代码


/*******************************************************************************
 * Copyright 2011-2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.fragment;

import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.listener.PauseOnScrollListener;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;
import com.nostra13.universalimageloader.sample.activity.SimpleImageActivity;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public abstract class AbsListViewBaseFragment extends BaseFragment {

	protected static final String STATE_PAUSE_ON_SCROLL = "STATE_PAUSE_ON_SCROLL";
	protected static final String STATE_PAUSE_ON_FLING = "STATE_PAUSE_ON_FLING";


    /**
     * AbsListView是ListView的父类
     *
     *
     *
     */

    protected AbsListView listView;

	protected boolean pauseOnScroll = false;
	protected boolean pauseOnFling = true;

	@Override
	public void onResume() {
		super.onResume();
		applyScrollListener();
	}

    /**
     * 创建菜单
     * @param menu
     */
	@Override
	public void onPrepareOptionsMenu(Menu menu) {
        /**
         * 短暂滑动式否暂停
         */
		MenuItem pauseOnScrollItem = menu.findItem(R.id.item_pause_on_scroll);
		pauseOnScrollItem.setVisible(true);
		pauseOnScrollItem.setChecked(pauseOnScroll);

        /**
         * 孟的滑动是否暂停
         */
		MenuItem pauseOnFlingItem = menu.findItem(R.id.item_pause_on_fling);
		pauseOnFlingItem.setVisible(true);
		pauseOnFlingItem.setChecked(pauseOnFling);
	}

    /**
     * 菜单点击事件
     * @param item
     * @return
     */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.item_pause_on_scroll:
                /**
                 * 短暂滑动式否暂停
                 */
				pauseOnScroll = !pauseOnScroll;
				item.setChecked(pauseOnScroll);
				applyScrollListener();
				return true;
			case R.id.item_pause_on_fling:
                /**
                 * 孟的滑动是否暂停
                 */
				pauseOnFling = !pauseOnFling;
				item.setChecked(pauseOnFling);
				applyScrollListener();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	protected void startImagePagerActivity(int position) {
        /**
         * 跳转到单个图片的实例
         */
		Intent intent = new Intent(getActivity(), SimpleImageActivity.class);
		intent.putExtra(Constants.Extra.FRAGMENT_INDEX, ImagePagerFragment.INDEX);
		intent.putExtra(Constants.Extra.IMAGE_POSITION, position);
		startActivity(intent);
	}

	private void applyScrollListener() {
        /*这个方法是干嘛用呢,主要是我们在使用ListView,GridView去加载图片的时候,有时候为了滑动更加的流畅,我们会选择手指在滑动或者猛地一滑动的时候不去加载图片,
        所以才提出了这么一个方法,那么要怎么用呢? 这里用到了PauseOnScrollListener这个类,使用很简单ListView.setOnScrollListener(new PauseOnScrollListener(pauseOnScroll
        , pauseOnFling )), pauseOnScroll控制我们缓慢滑动ListView,GridView是否停止加载图片,pauseOnFling 控制猛的滑动ListView,GridView是否停止加载图片*/
		listView.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), pauseOnScroll, pauseOnFling));
	}
}

其实也并不难就讲了两点:

1.菜单里设置ListView缓慢滑动和猛的缓动是否加载图片

2.startImagePagerActivity 跳转到单个图片实例


5.看看ImageListFragment这个类吧(LISTVIEW)


/*******************************************************************************
 * Copyright 2011-2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.fragment;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.display.CircleBitmapDisplayer;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class ImageListFragment extends AbsListViewBaseFragment {


	/**
	 * 这个I常量不陌生吧
	 * HomeActivity.class这个类中已经接触过了
	 *public 不同包中可以访问
	 *static 全局可以访问
	 *常量不能改变
	 */
	public static final int INDEX = 0;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fr_image_list, container, false);
		listView = (ListView) rootView.findViewById(android.R.id.list);
		((ListView) listView).setAdapter(new ImageAdapter(getActivity()));
		/**
		 * listView点击事件
		 */
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				startImagePagerActivity(position);
			}
		});
		return rootView;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		/**
		 * 销毁的时候清除数据
		 */
		AnimateFirstDisplayListener.displayedImages.clear();
	}

	/**
	 * 这是一个BaseAdapter
	 */
	private static class ImageAdapter extends BaseAdapter {

		private static final String[] IMAGE_URLS = Constants.IMAGES;

		private LayoutInflater inflater;
		private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();

		private DisplayImageOptions options;

		/**
		 * ImageLoader图片的显示选项
		 *
		 * 如有需要我们可以自己添加更多配置
		 */
		ImageAdapter(Context context) {
			inflater = LayoutInflater.from(context);

			options = new DisplayImageOptions.Builder()
					.showImageOnLoading(R.drawable.ic_stub)//默认图片
					.showImageForEmptyUri(R.drawable.ic_empty)//url为空时显示的图片
					.showImageOnFail(R.drawable.ic_error)//加载失败时显示的图片
					.cacheInMemory(true)//缓存到内存中
					.cacheOnDisk(true)//缓存到磁盘中
					.considerExifParams(true)
					.displayer(new CircleBitmapDisplayer(Color.WHITE, 5))
					.build();
		}

		@Override
		public int getCount() {
			return IMAGE_URLS.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;
			if (convertView == null) {
				view = inflater.inflate(R.layout.item_list_image, parent, false);
				holder = new ViewHolder();
				holder.text = (TextView) view.findViewById(R.id.text);
				holder.image = (ImageView) view.findViewById(R.id.image);
				view.setTag(holder);
			} else {
				holder = (ViewHolder) view.getTag();
			}

			holder.text.setText("Item " + (position + 1));

			/**
			 * 第一个参数:图片连接地址
			 *
			 * 第二个参数imageView控件
			 *
			 *	第三个参数 ImageLoader图片的显示选项
			 *
			 * animateFirstListener:ImageLoader监听
			 */
			ImageLoader.getInstance().displayImage(IMAGE_URLS[position], holder.image, options, animateFirstListener);

			return view;
		}
	}

	static class ViewHolder {
		TextView text;
		ImageView image;
	}

	/**
	 * 这是一个ImageLoader监听事件
	 */
	private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
		/**
		 * LinkedList是双向列表
		 *
		 * 多个线程同时访问一个LinkedList实例,而其中至少一个线程从结构上修改了列表,那么它就必须保持外部同步。
		 * (结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)
		 * 这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用Collections.synchronizedList方法将
		 * 该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问
		 *
		 */
		static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());

		/**
		 * loadComplete是图片加载完成之后的操作
		 * @param imageUri
		 * @param view
		 * @param loadedImage
		 */
		@Override
		public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
			if (loadedImage != null) {
				ImageView imageView = (ImageView) view;
				boolean firstDisplay = !displayedImages.contains(imageUri);//是否包含地址

				/**
				 * 没有加载购动画
				 */
				if (firstDisplay) {
					/**
					 * 显示图像淡入动画
					 *
					 * 第一个参数:图片
					 *
					 * 第2个参数:持续时间
					 */
					FadeInBitmapDisplayer.animate(imageView, 500);
					/**
					 * 地址添加进listView中
					 */
					displayedImages.add(imageUri);
				}
			}
		}
	}
}

这个类有四点内容:

配置图片的显示选项

加载图片

ImageLoaderr监听

加载图片动画以及判断





6 GridView加载图片(GRIDVIEW)


/*******************************************************************************
 * Copyright 2011-2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.fragment;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class ImageGridFragment extends AbsListViewBaseFragment {

    public static final int INDEX = 1;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fr_image_grid, container, false);
        listView = (GridView) rootView.findViewById(R.id.grid);
        ((GridView) listView).setAdapter(new ImageAdapter(getActivity()));
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            /**
             * 跳转到单个图片的实例
             */
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                startImagePagerActivity(position);
            }
        });
        return rootView;
    }

    private static class ImageAdapter extends BaseAdapter {

        /**
         * 图片地链接地址
         */
        private static final String[] IMAGE_URLS = Constants.IMAGES;

        private LayoutInflater inflater;

        private DisplayImageOptions options;

        ImageAdapter(Context context) {
            inflater = LayoutInflater.from(context);

            /**
             * ImageLoader图片的显示选项
             *
             * 如有需要我们可以自己添加更多配置
             */
            options = new DisplayImageOptions.Builder()
                    .showImageOnLoading(R.drawable.ic_stub)//默认图片
                    .showImageForEmptyUri(R.drawable.ic_empty)//url为空时显示的图片
                    .showImageOnFail(R.drawable.ic_error)//加载失败时显示的图片
                    .cacheInMemory(true)//开启缓存
                    .cacheOnDisk(true)//设置下载的图片是否缓存在SD卡中
                    .considerExifParams(true)是否考虑JPEG图像EXIF参数(旋转,翻转)
                    .bitmapConfig(Bitmap.Config.RGB_565)// default 设置图片的解码类型
                    .build();//创建
        }

        @Override
        public int getCount() {
            return IMAGE_URLS.length;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHolder holder;
            View view = convertView;
            if (view == null) {
                view = inflater.inflate(R.layout.item_grid_image, parent, false);
                holder = new ViewHolder();
                assert view != null;
                holder.imageView = (ImageView) view.findViewById(R.id.image);
                holder.progressBar = (ProgressBar) view.findViewById(R.id.progress);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }

            ImageLoader.getInstance()
                    .displayImage(IMAGE_URLS[position], holder.imageView, options, new SimpleImageLoadingListener() {
                        /**
                         *  参数1:加载的图片
                         *  参数2:控件
                         *  参数3:图片的显示选项
                         *  SimpleImageLoadingListener:图片的监听事件
                         *
                         * @param imageUri
                         * @param view
                         */
                        @Override
                        public void onLoadingStarted(String imageUri, View view) {
                            /**
                             * 图片加载中
                             */
                            holder.progressBar.setProgress(0);
                            holder.progressBar.setVisibility(View.VISIBLE);
                        }

                        @Override
                        public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                            /**
                             * 图片加载失败
                             */
                            holder.progressBar.setVisibility(View.GONE);
                        }

                        @Override
                        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                            /**
                             * 图片加载完的
                             */
                            holder.progressBar.setVisibility(View.GONE);
                        }
                    }, new ImageLoadingProgressListener() {
                        /**
                         * 显示图片的加载进度
                         * @param imageUri Image URI
                         * @param view     View for image. Can be <b>null</b>.
                         * @param current  Downloaded size in bytes
                         * @param total    Total size in bytes
                         */
                        @Override
                        public void onProgressUpdate(String imageUri, View view, int current, int total) {
                            holder.progressBar.setProgress(Math.round(100.0f * current / total));
                        }
                    });

            return view;
        }
    }

    static class ViewHolder {
        ImageView imageView;
        ProgressBar progressBar;
    }
}


这里跟ListView加载图片不同的是;

1:没有加载动画

2.加载的方式不一样,采用以下方式加载图片

            ImageLoader.getInstance()
                    .displayImage(IMAGE_URLS[position], holder.imageView, options, new SimpleImageLoadingListener() {
                        /**
                         *  参数1:加载的图片
                         *  参数2:控件
                         *  参数3:图片的显示选项
                         *  SimpleImageLoadingListener:图片的监听事件
                         *
                         * @param imageUri
                         * @param view
                         */
                        @Override
                        public void onLoadingStarted(String imageUri, View view) {
                            /**
                             * 图片加载中
                             */
                            holder.progressBar.setProgress(0);
                            holder.progressBar.setVisibility(View.VISIBLE);
                        }

                        @Override
                        public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                            /**
                             * 图片加载失败
                             */
                            holder.progressBar.setVisibility(View.GONE);
                        }

                        @Override
                        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                            /**
                             * 图片加载完的
                             */
                            holder.progressBar.setVisibility(View.GONE);
                        }
                    }, new ImageLoadingProgressListener() {
                        /**
                         * 显示图片的加载进度
                         * @param imageUri Image URI
                         * @param view     View for image. Can be <b>null</b>.
                         * @param current  Downloaded size in bytes
                         * @param total    Total size in bytes
                         */
                        @Override
                        public void onProgressUpdate(String imageUri, View view, int current, int total) {
                            holder.progressBar.setProgress(Math.round(100.0f * current / total));
                        }
                    });






7 ImagePager加载图片(VIEWPAGER)


/*******************************************************************************
 * Copyright 2011-2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.fragment;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Parcelable;
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.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class ImagePagerFragment extends BaseFragment {

	public static final int INDEX = 2;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fr_image_pager, container, false);
		ViewPager pager = (ViewPager) rootView.findViewById(R.id.pager);

		/**
		 * 通过setAdapter绑定ImageAdapter
		 */
		pager.setAdapter(new ImageAdapter(getActivity()));
		/**
		 *setCurrentItem:ViewPager 跳转到某个页面
		 */
		pager.setCurrentItem(getArguments().getInt(Constants.Extra.IMAGE_POSITION, 0));
		return rootView;
	}

	private static class ImageAdapter extends PagerAdapter {


		/**
		 *保存下载链接
		 */
		private static final String[] IMAGE_URLS = Constants.IMAGES;

		private LayoutInflater inflater;
		private DisplayImageOptions options;

		ImageAdapter(Context context) {
			inflater = LayoutInflater.from(context);

			/**
			 * ImageLoader的显示选项
			 */
			options = new DisplayImageOptions.Builder()
					.showImageForEmptyUri(R.drawable.ic_empty)
					.showImageOnFail(R.drawable.ic_error)
					.resetViewBeforeLoading(true)
					.cacheOnDisk(true)
					.imageScaleType(ImageScaleType.EXACTLY)
					.bitmapConfig(Bitmap.Config.RGB_565)
					.considerExifParams(true)
					.displayer(new FadeInBitmapDisplayer(300))
					.build();
		}

		/**
		 * 移除页面
		 * @param container
		 * @param position
		 * @param object
		 */
		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			container.removeView((View) object);
		}

		/**
		 * 页面数量
		 * @return
		 */
		@Override
		public int getCount() {
			return IMAGE_URLS.length;
		}

		/**
		 * 这个方法用来实例化页面
		 * @param view
		 * @param position
		 * @return
		 */
		@Override
		public Object instantiateItem(ViewGroup view, int position) {
			View imageLayout = inflater.inflate(R.layout.item_pager_image, view, false);
			assert imageLayout != null;
			ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image);
			final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading);

			/**
			 * 加载图片
			 */
			ImageLoader.getInstance().displayImage(IMAGE_URLS[position], imageView, options, new SimpleImageLoadingListener() {
				@Override
				public void onLoadingStarted(String imageUri, View view) {
					spinner.setVisibility(View.VISIBLE);
				}


				/**
				 * 获取异常信息
				 * @param imageUri
				 * @param view
				 * @param failReason
				 */
				@Override
				public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
					String message = null;
					switch (failReason.getType()) {
						case IO_ERROR:
							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(view.getContext(), message, Toast.LENGTH_SHORT).show();

					spinner.setVisibility(View.GONE);
				}

				@Override
				public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
					spinner.setVisibility(View.GONE);
				}
			});

			view.addView(imageLayout, 0);
			return imageLayout;
		}

		/**
		 * isViewFromObject方法是用来判断pager的一个view是否和instantiateItem方法返回的object有关联
		 * @param view
		 * @param object
		 * @return
		 */
		@Override
		public boolean isViewFromObject(View view, Object object) {
			return view.equals(object);
		}

		@Override
		public void restoreState(Parcelable state, ClassLoader loader) {
		}

		@Override
		public Parcelable saveState() {
			return null;
		}
	}
}

这里用到了ViewPager

有一点要注意

这里输出异常信息并用Toast提示


				/**
				 * 获取异常信息
				 * @param imageUri
				 * @param view
				 * @param failReason
				 */
				@Override
				public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
					String message = null;
					switch (failReason.getType()) {
						case IO_ERROR:
							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(view.getContext(), message, Toast.LENGTH_SHORT).show();






8 ImageGalleryFragment.class(画廊视图GALLERY)


/*******************************************************************************
 * Copyright 2011-2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.fragment;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import com.nostra13.universalimageloader.sample.Constants;
import com.nostra13.universalimageloader.sample.R;
import com.nostra13.universalimageloader.sample.activity.SimpleImageActivity;

/**
 * 画廊界面
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class ImageGalleryFragment extends BaseFragment {

	public static final int INDEX = 3;

	@SuppressWarnings("deprecation")
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fr_image_gallery, container, false);
		Gallery gallery = (Gallery) rootView.findViewById(R.id.gallery);
		gallery.setAdapter(new ImageAdapter(getActivity()));
		gallery.setOnItemClickListener(new OnItemClickListener() {
			/**
			 * 跳转到单个图片的实例
			 * @param parent
			 * @param view
			 * @param position
			 * @param id
			 */
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				startImagePagerActivity(position);
			}
		});
		return rootView;
	}


	private void startImagePagerActivity(int position) {
		Intent intent = new Intent(getActivity(), SimpleImageActivity.class);
		intent.putExtra(Constants.Extra.FRAGMENT_INDEX, ImagePagerFragment.INDEX);
		intent.putExtra(Constants.Extra.IMAGE_POSITION, position);
		startActivity(intent);
	}

	private static class ImageAdapter extends BaseAdapter {

		private static final String[] IMAGE_URLS = Constants.IMAGES;

		private LayoutInflater inflater;

		private DisplayImageOptions options;

		ImageAdapter(Context context) {
			inflater = LayoutInflater.from(context);

			/**
			 * ImageLoader的图片显示选项
			 */
			options = new DisplayImageOptions.Builder()
					.showImageOnLoading(R.drawable.ic_stub)
					.showImageForEmptyUri(R.drawable.ic_empty)
					.showImageOnFail(R.drawable.ic_error)
					.cacheInMemory(true)
					.cacheOnDisk(true)
					.considerExifParams(true)
					.bitmapConfig(Bitmap.Config.RGB_565)
					.displayer(new RoundedBitmapDisplayer(20))
					.build();
		}

		@Override
		public int getCount() {
			return IMAGE_URLS.length;
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ImageView imageView = (ImageView) convertView;
			if (imageView == null) {
				imageView = (ImageView) inflater.inflate(R.layout.item_gallery_image, parent, false);
			}
			/**
			 * 加载图片
			 */
			ImageLoader.getInstance().displayImage(IMAGE_URLS[position], imageView, options);
			return imageView;
		}
	}
}

画廊视图没什么好说的




9.ComplexImageActivity.class(VIEWPAGER)

/*******************************************************************************
 * Copyright 2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.sample.activity;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.nostra13.universalimageloader.sample.R;
import com.nostra13.universalimageloader.sample.fragment.ImageGridFragment;
import com.nostra13.universalimageloader.sample.fragment.ImageListFragment;

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class ComplexImageActivity extends FragmentActivity {

	private static final String STATE_POSITION = "STATE_POSITION";

	private ViewPager pager;

	@TargetApi(Build.VERSION_CODES.GINGERBREAD)
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.ac_complex);

		/**
		 * FragmentActivity的状态信息
		 *
		 *savedInstanceState.getInt:返回与给定键关联的值,或0 if对于给定的键,不存在所需类型的映射。
		 *
		 */
		int pagerPosition = savedInstanceState == null ? 0 : savedInstanceState.getInt(STATE_POSITION);

		/**
		 * 标题栏
		 */
		pager = (ViewPager) findViewById(R.id.pager);
		/**
		 * 通过setAdapter绑定ImageAdapter
		 */
		pager.setAdapter(new ImagePagerAdapter(getSupportFragmentManager()));

		/**
		 * 跳转到指定的页面
		 */
		pager.setCurrentItem(pagerPosition);
	}

	@TargetApi(Build.VERSION_CODES.GINGERBREAD)

	/**
	 * 保存Activity状态信息
	 *
	 * 这里保存当前页面
	 */
	@Override
	public void onSaveInstanceState(Bundle outState) {
		outState.putInt(STATE_POSITION, pager.getCurrentItem());
	}

	/**
	 * FragmentPagerAdapter适配器
	 */
	private class ImagePagerAdapter extends FragmentPagerAdapter {

		Fragment listFragment;
		Fragment gridFragment;

		ImagePagerAdapter(FragmentManager fm) {
			super(fm);
			listFragment = new ImageListFragment();
			gridFragment = new ImageGridFragment();
		}

		@Override
		public int getCount() {
			return 2;
		}

		/**
		 * 页面数量
		 * @param position
		 * @return
		 */
		@Override
		public Fragment getItem(int position) {
			switch (position) {
				case 0:
					return listFragment;
				case 1:
					return gridFragment;
				default:
					return null;
			}
		}

		/**
		 * 设置页面标题
		 * @param position
		 * @return
		 */
		@Override
		public CharSequence getPageTitle(int position) {
			switch (position) {
				case 0:
					return getString(R.string.title_list);
				case 1:
					return getString(R.string.title_grid);
				default:
					return null;
			}
		}
	}
}

这里有两个页面
ListView+GridView
ViewPager实现切换,PagerTitleStrip实现标题栏





10 再来说一下ImagePagerFragment.class类


我们可以看到LISTVIEW,GRIDVIEW,GALLERY,VIEWPAGERZ这几个界面setOnItemClickListener时都会进入一个新的界面,这个界面用到了ViewPager,那么这个界面用到了哪个类呢。从代码中我们可找到它用到了这个类setOnItemClickListener.class ,ImageLoader作者写的Demo是不是很棒。



源码下载地址

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值