ImageLoader异步加载图片

来源:互联网 发布:macbook windows 截屏 编辑:程序博客网 时间:2024/06/05 16:44

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

好了废话不说了今天来学习一个开源库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")@Overridepublic 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 MiBconfig.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";@Overridepublic 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);}/** * 按后退建是停止加载 */@Overridepublic void onBackPressed() {ImageLoader.getInstance().stop();super.onBackPressed();}/** * 显示菜单 * @param menu * @return */@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main_menu, menu);return true;}@Overridepublic 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() {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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);}@Overridepublic 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;@Overridepublic void onResume() {super.onResume();applyScrollListener();}    /**     * 创建菜单     * @param menu     */@Overridepublic 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     */@Overridepublic 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;@Overridepublic 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() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {startImagePagerActivity(position);}});return rootView;}@Overridepublic 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();}@Overridepublic int getCount() {return IMAGE_URLS.length;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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 */@Overridepublic 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;@Overridepublic 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 */@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);}/** * 页面数量 * @return */@Overridepublic int getCount() {return IMAGE_URLS.length;}/** * 这个方法用来实例化页面 * @param view * @param position * @return */@Overridepublic 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() {@Overridepublic void onLoadingStarted(String imageUri, View view) {spinner.setVisibility(View.VISIBLE);}/** * 获取异常信息 * @param imageUri * @param view * @param failReason */@Overridepublic 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);}@Overridepublic 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 */@Overridepublic boolean isViewFromObject(View view, Object object) {return view.equals(object);}@Overridepublic void restoreState(Parcelable state, ClassLoader loader) {}@Overridepublic Parcelable saveState() {return null;}}}

这里用到了ViewPager

有一点要注意

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


/** * 获取异常信息 * @param imageUri * @param view * @param failReason */@Overridepublic 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")@Overridepublic 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 */@Overridepublic 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();}@Overridepublic int getCount() {return IMAGE_URLS.length;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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)@Overridepublic 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状态信息 * * 这里保存当前页面 */@Overridepublic 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();}@Overridepublic int getCount() {return 2;}/** * 页面数量 * @param position * @return */@Overridepublic Fragment getItem(int position) {switch (position) {case 0:return listFragment;case 1:return gridFragment;default:return null;}}/** * 设置页面标题 * @param position * @return */@Overridepublic 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是不是很棒。



源码下载地址

原创粉丝点击