«

Android UI-开源框架ImageLoader的完美例子(异步加载大量图片)

时间:2024-3-2 17:49     作者:韩俊     分类: Android


Android开源框架ImageLoader的完美例子


很多人都在讨论如何让图片能在异步加载更加流畅,可以显示大量图片,在拖动ListView的时候不会出现卡的现象。关于ImageLoader这个开源框架的使用有很多网友都介绍过,不过还不够清楚,这里有一个关于这个开源项目的完美例子,ListView的图片加载、GridView的图片加载、ViewPager的图片加载、Gallery画廊的图片加载、Widget的使用。很完善的一个例子,在这里我把所有界面效果做出博客分享出来,需要源码的朋友到我的资源页下载

下载地址:http://download.csdn.net/detail/wwj_748/5975847



要使用ImageLoader就要到这里下载jar包:

https://github.com/nostra13/Android-Universal-Image-Loader

然后导入项目中去就行了

项目文档结构图:


从界面说起,界面本身是没什么好说的,就是如何在xml当中进行定义罢了

有以下这么多个布局文件


一个一个来看呗

首先是这样的效果

这个在Android4.2.2比较好看,在Android2.3.3就显得比较挫。


/2013.8.19_Universal_Image_Loader_Demo/res/layout/ac_home.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

&lt;LinearLayout  
    android:layout_width=&quot;fill_parent&quot;  
    android:layout_height=&quot;fill_parent&quot;  
    android:orientation=&quot;vertical&quot; &gt;  

    &lt;TextView  
        android:layout_width=&quot;fill_parent&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:gravity=&quot;center&quot;  
        android:paddingBottom=&quot;10dip&quot;  
        android:paddingTop=&quot;20dip&quot;  
        android:text=&quot;@string/label_activity_examples&quot;  
        android:textSize=&quot;24sp&quot; /&gt;  

    &lt;Button  
        android:layout_width=&quot;fill_parent&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_margin=&quot;10dip&quot;  
        android:onClick=&quot;onImageListClick&quot;  
        android:text=&quot;@string/button_image_list&quot; /&gt;  

    &lt;Button  
        android:layout_width=&quot;fill_parent&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_margin=&quot;10dip&quot;  
        android:onClick=&quot;onImageGridClick&quot;  
        android:text=&quot;@string/button_image_grid&quot; /&gt;  

    &lt;Button  
        android:layout_width=&quot;fill_parent&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_margin=&quot;10dip&quot;  
        android:onClick=&quot;onImagePagerClick&quot;  
        android:text=&quot;@string/button_image_pager&quot; /&gt;  

    &lt;Button  
        android:layout_width=&quot;fill_parent&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_margin=&quot;10dip&quot;  
        android:onClick=&quot;onImageGalleryClick&quot;  
        android:text=&quot;@string/button_image_gallery&quot; /&gt;  
&lt;/LinearLayout&gt;  

</ScrollView>



列表异步加载图片效果

/2013.8.19_Universal_Image_Loader_Demo/res/layout/ac_image_list.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />



/2013.8.19_Universal_Image_Loader_Demo/res/layout/item_list_image.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:layout_width="fill_parent"
android:layout_height="wrap_content" >

&lt;ImageView  
    android:id=&quot;@&#43;id/image&quot;  
    android:layout_width=&quot;72dip&quot;  
    android:layout_height=&quot;72dip&quot;  
    android:layout_margin=&quot;3dip&quot;  
    android:adjustViewBounds=&quot;true&quot;  
    android:contentDescription=&quot;@string/descr_image&quot;  
    android:scaleType=&quot;centerCrop&quot; /&gt;  

&lt;TextView  
    android:id=&quot;@&#43;id/text&quot;  
    android:layout_width=&quot;fill_parent&quot;  
    android:layout_height=&quot;wrap_content&quot;  
    android:layout_gravity=&quot;left|center_vertical&quot;  
    android:layout_marginLeft=&quot;20dip&quot;  
    android:textSize=&quot;22sp&quot; /&gt;  

</LinearLayout>



GridView异步加载图片显示


/2013.8.19_Universal_Image_Loader_Demo/res/layout/ac_image_grid.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip"
android:padding="4dip" />




/2013.8.19_Universal_Image_Loader_Demo/res/layout/item_grid_image.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="120dip"
android:adjustViewBounds="true"
android:contentDescription="@string/descr_image"
android:scaleType="centerCrop" />




ViewPager异步加载图片显示

/2013.8.19_Universal_Image_Loader_Demo/res/layout/ac_image_pager.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />



/2013.8.19_Universal_Image_Loader_Demo/res/layout/item_pager_image.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="1dip" >

&lt;ImageView  
    android:id=&quot;@&#43;id/image&quot;  
    android:layout_width=&quot;wrap_content&quot;  
    android:layout_height=&quot;wrap_content&quot;  
    android:layout_gravity=&quot;center&quot;  
    android:adjustViewBounds=&quot;true&quot;  
    android:contentDescription=&quot;@string/descr_image&quot; /&gt;  

&lt;ProgressBar  
    android:id=&quot;@&#43;id/loading&quot;  
    android:layout_width=&quot;wrap_content&quot;  
    android:layout_height=&quot;wrap_content&quot;  
    android:layout_gravity=&quot;center&quot;  
    android:visibility=&quot;gone&quot; /&gt;  

</FrameLayout>




Gallery画廊异步加载图片显示

/2013.8.19_Universal_Image_Loader_Demo/res/layout/ac_image_gallery.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<Gallery xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:id="@+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:spacing="1dip" />




/2013.8.19_Universal_Image_Loader_Demo/res/layout/item_gallery_image.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android&quot;
android:id="@+id/image"
android:layout_width="120dip"
android:layout_height="120dip"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:contentDescription="@string/descr_image"
android:scaleType="centerCrop" />




还有一个就是桌面小部件


以上只是布局文件,没有什么可以说,具体Activity代码实现如下:


先是这个:

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/HomeActivity.java

主界面Activity代码

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

import static com.nostra13.example.universalimageloader.Constants.IMAGES;

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

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.nostra13.example.universalimageloader.Constants.Extra;
import com.nostra13.universalimageloader.utils.L;

/**

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

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

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

    // 定义文件对象,目录:/mnt/sdcard, 文件名:TEST_FILE_NAME  
    File testImageOnSdCard = new File(&quot;/mnt/sdcard&quot;, TEST_FILE_NAME);  
    if (!testImageOnSdCard.exists()) {  // 如果文件不存在  
        // 把文件复制到SD卡  
        copyTestImageToSdCard(testImageOnSdCard);  
    }  

    }

    // 点击进入ListView展示界面
    public void onImageListClick(View view) {
    Intent intent = new Intent(this, ImageListActivity.class);
    intent.putExtra(Extra.IMAGES, IMAGES);
    startActivity(intent);
    }

    // 点击进入GridView展示界面
    public void onImageGridClick(View view) {
    Intent intent = new Intent(this, ImageGridActivity.class);
    intent.putExtra(Extra.IMAGES, IMAGES);
    startActivity(intent);
    }

    // 点击进入ViewPager展示界面
    public void onImagePagerClick(View view) {
    Intent intent = new Intent(this, ImagePagerActivity.class);
    intent.putExtra(Extra.IMAGES, IMAGES);
    startActivity(intent);
    }

    // 点击进入画廊展示界面
    public void onImageGalleryClick(View view) {
    Intent intent = new Intent(this, ImageGalleryActivity.class);
    intent.putExtra(Extra.IMAGES, IMAGES);
    startActivity(intent);
    }

    @Override
    public void onBackPressed() {
    imageLoader.stop(); // 停止加载图片
    super.onBackPressed();
    }

    /**

    • 开一个线程把assert目录下的图片复制到SD卡目录下
    • @param testImageOnSdCard
      */
      private void copyTestImageToSdCard(final File testImageOnSdCard) {
      new Thread(new Runnable() {
      @Override
      public void run() {
      try {
      InputStream is = getAssets().open(TEST_FILE_NAME);
      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 {
      fos.flush(); // 写入SD卡
      fos.close(); // 关闭输出流
      is.close(); // 关闭输入流
      }
      } catch (IOException e) {
      L.w("Can't copy test image onto SD card");
      }
      }
      }).start(); // 启动线程
      }
      }



/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/BaseActivity.java

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;

import com.nostra13.universalimageloader.core.ImageLoader;

/**

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

    protected ImageLoader imageLoader = ImageLoader.getInstance();

    @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.clearMemoryCache(); // 清除内存缓存
    return true;
    case R.id.item_clear_disc_cache:
    imageLoader.clearDiscCache(); // 清除SD卡中的缓存
    return true;
    default:
    return false;
    }
    }
    }




/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/AbsListViewBaseActivity.java

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;

import com.nostra13.universalimageloader.core.assist.PauseOnScrollListener;

/**

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
    */
    public class AbsListViewBaseActivity extends BaseActivity {

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

    protected AbsListView listView;

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

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    pauseOnScroll = savedInstanceState.getBoolean(STATE_PAUSE_ON_SCROLL, false);
    pauseOnFling = savedInstanceState.getBoolean(STATE_PAUSE_ON_FLING, true);
    }

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

    private void applyScrollListener() {
    listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(STATE_PAUSE_ON_SCROLL, pauseOnScroll);
    outState.putBoolean(STATE_PAUSE_ON_FLING, pauseOnFling);
    }

    @Override
    public boolean 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);  
    return true;  

    }

    @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);
    }
    }
    }




/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/Constants.java

常量类代码

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

/**



/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImageListActivity.java

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

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

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
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.example.universalimageloader.Constants.Extra;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;

/**

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
    */
    public class ImageListActivity extends AbsListViewBaseActivity {

    DisplayImageOptions options; // DisplayImageOptions是用于设置图片显示的类

    String[] imageUrls; // 图片路径

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

    Bundle bundle = getIntent().getExtras();  
    imageUrls = bundle.getStringArray(Extra.IMAGES);  
    
    // 使用DisplayImageOptions.Builder()创建DisplayImageOptions  
    options = new DisplayImageOptions.Builder()  
        .showStubImage(R.drawable.ic_stub)          // 设置图片下载期间显示的图片  
        .showImageForEmptyUri(R.drawable.ic_empty)  // 设置图片Uri为空或是错误的时候显示的图片  
        .showImageOnFail(R.drawable.ic_error)       // 设置图片加载或解码过程中发生错误显示的图片      
        .cacheInMemory(true)                        // 设置下载的图片是否缓存在内存中  
        .cacheOnDisc(true)                          // 设置下载的图片是否缓存在SD卡中  
        .displayer(new RoundedBitmapDisplayer(20))  // 设置成圆角图片  
        .build();                                   // 创建配置过得DisplayImageOption对象  
    
    listView = (ListView) findViewById(android.R.id.list);  
    ((ListView) listView).setAdapter(new ItemAdapter());  
    listView.setOnItemClickListener(new OnItemClickListener() {  
        @Override  
        public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {  
            // 点击列表项转入ViewPager显示界面  
            startImagePagerActivity(position);        
        }  
    });  

    }

    @Override
    public void onBackPressed() {
    AnimateFirstDisplayListener.displayedImages.clear();
    super.onBackPressed();
    }

    private void startImagePagerActivity(int position) {
    Intent intent = new Intent(this, ImagePagerActivity.class);
    intent.putExtra(Extra.IMAGES, imageUrls);
    intent.putExtra(Extra.IMAGE_POSITION, position);
    startActivity(intent);
    }

    /**

    • 自定义列表项适配器
    • */
      class ItemAdapter extends BaseAdapter {

      private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();

      private class ViewHolder {
      public TextView text;
      public ImageView image;
      }

      @Override
      public int getCount() {
      return imageUrls.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 = getLayoutInflater().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); // 给View添加一个格外的数据
      } else {
      holder = (ViewHolder) view.getTag(); // 把数据取出来
      }

      holder.text.setText(&quot;Item &quot; &#43; (position &#43; 1));  // TextView设置文本  
      
      /** 
       * 显示图片 
       * 参数1:图片url 
       * 参数2:显示图片的控件 
       * 参数3:显示图片的设置 
       * 参数4:监听器 
       */  
      imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);  
      
      return view;  

      }
      }

    /**

    • 图片加载第一次显示监听器
    • @author Administrator
    • */
      private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {

      static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());

      @Override
      public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
      if (loadedImage != null) {
      ImageView imageView = (ImageView) view;
      // 是否第一次显示
      boolean firstDisplay = !displayedImages.contains(imageUri);
      if (firstDisplay) {
      // 图片淡入效果
      FadeInBitmapDisplayer.animate(imageView, 500);
      displayedImages.add(imageUri);
      }
      }
      }
      }
      }



/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImageGridActivity.java

网格视图Activity

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
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 com.nostra13.example.universalimageloader.Constants.Extra;
import com.nostra13.universalimageloader.core.DisplayImageOptions;

/**

  • 网格视图显示Activity
  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
    */
    public class ImageGridActivity extends AbsListViewBaseActivity {

    String[] imageUrls; // 图片Url

    DisplayImageOptions options; // 显示图片的设置

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

    Bundle bundle = getIntent().getExtras();  
    imageUrls = bundle.getStringArray(Extra.IMAGES);  
    
    options = new DisplayImageOptions.Builder()  
        .showStubImage(R.drawable.ic_stub)  
        .showImageForEmptyUri(R.drawable.ic_empty)  
        .showImageOnFail(R.drawable.ic_error)  
        .cacheInMemory(true)  
        .cacheOnDisc(true)  
        .bitmapConfig(Bitmap.Config.RGB_565)     //设置图片的解码类型  
        .build();  
    
    listView = (GridView) findViewById(R.id.gridview);  
    ((GridView) listView).setAdapter(new ImageAdapter());           // 填充数据  
    listView.setOnItemClickListener(new OnItemClickListener() {  
        @Override  
        public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {  
            startImagePagerActivity(position);  
        }  
    });  

    }

    private void startImagePagerActivity(int position) {
    Intent intent = new Intent(this, ImagePagerActivity.class);
    intent.putExtra(Extra.IMAGES, imageUrls);
    intent.putExtra(Extra.IMAGE_POSITION, position);
    startActivity(intent);
    }

    public class ImageAdapter extends BaseAdapter {
    @Override
    public int getCount() {
    return imageUrls.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 ImageView imageView;  
        if (convertView == null) {  
            imageView = (ImageView) getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);  
        } else {  
            imageView = (ImageView) convertView;  
        }  
    
        // 将图片显示任务增加到执行池,图片将被显示到ImageView当轮到此ImageView  
        imageLoader.displayImage(imageUrls[position], imageView, options);  
    
        return imageView;  
    }  

    }
    }




/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImagePagerActivity.java

ViewPager视图Activity

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

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.example.universalimageloader.Constants.Extra;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

/**

  • ViewPager页面显示Activity
  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
    */
    public class ImagePagerActivity extends BaseActivity {

    private static final String STATE_POSITION = "STATE_POSITION";

    DisplayImageOptions options;

    ViewPager pager;

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ac_image_pager);

    Bundle bundle = getIntent().getExtras();  
    String[] imageUrls = bundle.getStringArray(Extra.IMAGES);  
    // 当前显示View的位置  
    int pagerPosition = bundle.getInt(Extra.IMAGE_POSITION, 0);  
    
    // 如果之前有保存用户数据  
    if (savedInstanceState != null) {  
        pagerPosition = savedInstanceState.getInt(STATE_POSITION);  
    }  
    
    options = new DisplayImageOptions.Builder()  
        .showImageForEmptyUri(R.drawable.ic_empty)  
        .showImageOnFail(R.drawable.ic_error)  
        .resetViewBeforeLoading(true)  
        .cacheOnDisc(true)  
        .imageScaleType(ImageScaleType.EXACTLY)  
        .bitmapConfig(Bitmap.Config.RGB_565)  
        .displayer(new FadeInBitmapDisplayer(300))  
        .build();  
    
    pager = (ViewPager) findViewById(R.id.pager);  
    pager.setAdapter(new ImagePagerAdapter(imageUrls));  
    pager.setCurrentItem(pagerPosition);    // 显示当前位置的View  

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    // 保存用户数据
    outState.putInt(STATE_POSITION, pager.getCurrentItem());
    }

    private class ImagePagerAdapter extends PagerAdapter {

    private String[] images;  
    private LayoutInflater inflater;  
    
    ImagePagerAdapter(String[] images) {  
        this.images = images;  
        inflater = getLayoutInflater();  
    }  
    
    @Override  
    public void destroyItem(ViewGroup container, int position, Object object) {  
        ((ViewPager) container).removeView((View) object);  
    }  
    
    @Override  
    public void finishUpdate(View container) {  
    }  
    
    @Override  
    public int getCount() {  
        return images.length;  
    }  
    
    @Override  
    public Object instantiateItem(ViewGroup view, int position) {  
        View imageLayout = inflater.inflate(R.layout.item_pager_image, view, false);  
        ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image);  
        final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading);  
    
        imageLoader.displayImage(images[position], imageView, options, new SimpleImageLoadingListener() {  
            @Override  
            public void onLoadingStarted(String imageUri, View view) {  
                spinner.setVisibility(View.VISIBLE);  
            }  
    
            @Override  
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {  
                String message = null;  
                switch (failReason.getType()) {     // 获取图片失败类型  
                    case IO_ERROR:              // 文件I/O错误  
                        message = &quot;Input/Output error&quot;;  
                        break;  
                    case DECODING_ERROR:        // 解码错误  
                        message = &quot;Image can't be decoded&quot;;  
                        break;  
                    case NETWORK_DENIED:        // 网络延迟  
                        message = &quot;Downloads are denied&quot;;  
                        break;  
                    case OUT_OF_MEMORY:         // 内存不足  
                        message = &quot;Out Of Memory error&quot;;  
                        break;  
                    case UNKNOWN:               // 原因不明  
                        message = &quot;Unknown error&quot;;  
                        break;  
                }  
                Toast.makeText(ImagePagerActivity.this, message, Toast.LENGTH_SHORT).show();  
    
                spinner.setVisibility(View.GONE);  
            }  
    
            @Override  
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {  
                spinner.setVisibility(View.GONE);       // 不显示圆形进度条  
            }  
        });  
    
        ((ViewPager) view).addView(imageLayout, 0);     // 将图片增加到ViewPager  
        return imageLayout;  
    }  
    
    @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;  
    }  
    
    @Override  
    public void startUpdate(View container) {  
    }  

    }
    }



/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImageGalleryActivity.java

画廊视图的Activity

[java] view
plaincopy

/***

  • 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.example.universalimageloader;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
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.example.universalimageloader.Constants.Extra;
import com.nostra13.universalimageloader.core.DisplayImageOptions;

/**

  • 画廊视图Activity
  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
    */
    @SuppressWarnings("deprecation")
    public class ImageGalleryActivity extends BaseActivity {

    String[] imageUrls;

    DisplayImageOptions options;

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ac_image_gallery);

    Bundle bundle = getIntent().getExtras();  
    imageUrls = bundle.getStringArray(Extra.IMAGES);  
    
    options = new DisplayImageOptions.Builder()  
        .showStubImage(R.drawable.ic_stub)  
        .showImageForEmptyUri(R.drawable.ic_empty)  
        .showImageOnFail(R.drawable.ic_error)  
        .cacheInMemory(true)  
        .cacheOnDisc(true)  
        .bitmapConfig(Bitmap.Config.RGB_565)  
        .build();  
    
    // 自API 16之后就被抛弃了  
    Gallery gallery = (Gallery) findViewById(R.id.gallery);  
    gallery.setAdapter(new ImageGalleryAdapter());  
    gallery.setOnItemClickListener(new OnItemClickListener() {  
        @Override  
        public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {  
            startImagePagerActivity(position);  
        }  
    });  

    }

    private void startImagePagerActivity(int position) {
    Intent intent = new Intent(this, ImagePagerActivity.class);
    intent.putExtra(Extra.IMAGES, imageUrls);
    intent.putExtra(Extra.IMAGE_POSITION, position);
    startActivity(intent);
    }

    private class ImageGalleryAdapter extends BaseAdapter {
    @Override
    public int getCount() {
    return imageUrls.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) getLayoutInflater().inflate(R.layout.item_gallery_image, parent, false);  
        }  
        imageLoader.displayImage(imageUrls[position], imageView, options);  
        return imageView;  
    }  

    }
    }



关于桌面控件的代码我就不贴了,朋友们可以自己下载我这个Demo


还有就是Manifest文件代码

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android&quot;
package="com.nostra13.example.universalimageloader"
android:versionCode="35"
android:versionName="1.8.7" >

&lt;uses-sdk  
    android:minSdkVersion=&quot;5&quot;  
    android:targetSdkVersion=&quot;16&quot; /&gt;  

&lt;!-- 网络访问权限 --&gt;  
&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;  
&lt;!-- 文件写入SD卡权限 --&gt;  
&lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;  

&lt;application  
    android:name=&quot;.UILApplication&quot;  
    android:icon=&quot;@drawable/ic_launcher&quot;  
    android:label=&quot;@string/app_name&quot; &gt;  
    &lt;activity  
        android:name=&quot;.HomeActivity&quot;  
        android:label=&quot;@string/app_name&quot; &gt;  
        &lt;intent-filter&gt;  
            &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;  

            &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;  
        &lt;/intent-filter&gt;  
    &lt;/activity&gt;  
    &lt;activity  
        android:name=&quot;.ImageListActivity&quot;  
        android:label=&quot;@string/ac_name_image_list&quot; /&gt;  
    &lt;activity  
        android:name=&quot;.ImageGridActivity&quot;  
        android:label=&quot;@string/ac_name_image_grid&quot; /&gt;  
    &lt;activity  
        android:name=&quot;.ImagePagerActivity&quot;  
        android:label=&quot;@string/ac_name_image_pager&quot; /&gt;  
    &lt;activity  
        android:name=&quot;.ImageGalleryActivity&quot;  
        android:label=&quot;@string/ac_name_image_gallery&quot; /&gt;  

    &lt;!-- Widget --&gt;  
    &lt;receiver android:name=&quot;.widget.UILWidgetProvider&quot; &gt;  
        &lt;meta-data  
            android:name=&quot;android.appwidget.provider&quot;  
            android:resource=&quot;@xml/widget_provider&quot; /&gt;  

        &lt;intent-filter&gt;  
            &lt;action android:name=&quot;android.appwidget.action.APPWIDGET_UPDATE&quot; /&gt;  
        &lt;/intent-filter&gt;  
    &lt;/receiver&gt;  
&lt;/application&gt;  

</manifest>




以上的代码已经很详尽了,读者可以把它整合到你的项目当中,就可以实现完美异步加载图片。在这里要感谢那些为我们开源的大神们,他们的贡献让我们这些开发者更快更有效的完成工作,希望我们的开源会越做越好,我相信我们的开发者有这个能力。

标签: android

热门推荐