1. 程式人生 > >ViewPager結合ImageView實現圖片輪播的例項

ViewPager結合ImageView實現圖片輪播的例項

1、SlideShowView的佈局檔案:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"	
android:layout_width="match_parent"	
android:layout_height="match_parent" >	
<android.support.v4.view.ViewPager		
android:id="@+id/viewPager"		
android:layout_width="match_parent"		
android:layout_height="match_parent" />
<!--此LinearLayout用來小圓點-->	
<LinearLayout		
android:id="@+id/linearlayout"		
android:layout_width="match_parent"		
android:layout_height="wrap_content"		
android:layout_alignParentBottom="true"		
android:gravity="center"		
android:orientation="horizontal"		
android:padding="5dp" >	
</LinearLayout>
</RelativeLayout>
2、Drawble中繪製圓點:
<!-- 廣告圓點未選中 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    android:useLevel="false">
    <solid android:color="#33000000" />
   <corners android:radius="5dip" />
    <size android:width= "7dp"
        android:height= "7dp" />
</shape>

<!-- 廣告圓點選中 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    android:useLevel= "false" >
    <solid android:color="#aa3C3C3C" />
    <corners android:radius="5dip" />
    <size android:width= "7dp"
        android:height= "7dp" />
    />
3、SlideShowView類的具體實現程式碼:
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.beidougd.bdg.activity.AdsActivity;
import com.beidougd.bdgc.R;
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 java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by yr01 on 2015/12/15.
 */
public class SlideShowView extends FrameLayout{
    private final static boolean isAutoPlay = true;
    private List<String> imageUris;
    private List<String> imageAdsuris;
    private DisplayImageOptions options;
    private List<ImageView> imageViewsList;
    private List<ImageView> dotViewsList;
    private LinearLayout mLinearLayout;
    private ViewPager mViewPager;
    private int currentItem= 0;
    private ScheduledExecutorService scheduledExecutorService;
    private ImageView viewDot;
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            mViewPager.setCurrentItem(currentItem);
        }
    };
    public SlideShowView(Context context) {
        this(context,null);
    }
    public SlideShowView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public SlideShowView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
        initUI(context);
//        if(!(imageUris.size()<=0))
//        {
//            setImageUris(imageUris,imageAduris);
// }
        if(isAutoPlay){
            startPlay();
        }
    }
    private void initUI(Context context){
        options=new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.ad_01)
                .showImageOnFail(R.drawable.ad_01)
                .cacheInMemory(true)                        // 設定下載的圖片是否快取在記憶體中
                .cacheOnDisc(true)                          // 設定下載的圖片是否快取在SD卡中// 設定成圓角圖片
                .build();                                   // 建立配置過得DisplayImageOption物件
        imageViewsList = new ArrayList<ImageView>();
        dotViewsList = new ArrayList<ImageView>();
        imageUris=new ArrayList<String>();
        imageAdsuris=new ArrayList<String>();
       LayoutInflater.from(context).inflate(R.layout.layout_slideshow, this, true);
        mLinearLayout=(LinearLayout)findViewById(R.id.linearlayout_dot);
        mViewPager = (ViewPager) findViewById(R.id.viewPager);
    }
    public void setImageUris(List<String> imageuris,List<String> imageAduris){
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration
                .Builder(getContext())
                .threadPoolSize(4)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .discCacheFileNameGenerator(new Md5FileNameGenerator())// 將儲存的時候的URI名稱用MD5
                .writeDebugLogs() // Remove for release app
                .build();
        ImageLoader.getInstance().init(configuration);

        for(int i=0;i<imageuris.size();i++){
            imageUris.add(imageuris.get(i));
            imageAdsuris.add(imageAduris.get(i));
        }
        LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
        lp.setMargins(5, 0, 0, 0);
        for(int i=0;i<imageUris.size();i++){
            ImageView imageView=new ImageView(getContext());
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);//鋪滿螢幕
            System.out.println("ImageUrl:"+imageUris.get(i));
            ImageLoader.getInstance().displayImage(imageUris.get(i), imageView,options);
            imageViewsList.add(imageView);

            if(imageViewsList!=null){
                imageView=imageViewsList.get(i);
               final String Adurl=imageAdsuris.get(i);
                imageView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent=new Intent(getContext(), AdsActivity.class);
                        intent.putExtra("URL",Adurl);
                        getContext().startActivity(intent);
                    }
                });
            }

            viewDot =new ImageView(getContext());
            if(i == 0){
                viewDot.setBackgroundResource(R.drawable.dot_focused);
            }else{
                viewDot.setBackgroundResource(R.drawable.dot_normal);
            }
            viewDot.setLayoutParams(lp);
            dotViewsList.add(viewDot);
            mLinearLayout.addView(viewDot);
        }
        mViewPager.setFocusable(true);
        mViewPager.setAdapter(new MyPagerAdapter());
        mViewPager.setOnPageChangeListener(new MyPageChangeListener());	}
    private void startPlay(){
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 1, 4, TimeUnit.SECONDS);
    }
    public  void removeView(){
        imageUris.clear();
        imageAdsuris.clear();
        imageViewsList.clear();
        dotViewsList.clear();
        mLinearLayout.removeAllViews();

        Log.i("imageViewsList", imageViewsList.size() + "");
        Log.i("imageUris", imageUris.size() + "");
        Log.i("imageAdsuris", imageAdsuris.size() + "");
        Log.i("dotViewsList",dotViewsList.size()+"");
        Log.i("mLinearLayout",mLinearLayout.getChildCount()+"");
       // mLinearLayout.removeAllViewsInLayout();
    }
    @SuppressWarnings("unused")
    private void stopPlay(){
        scheduledExecutorService.shutdown();
    }
    private void setImageBackground(int selectItems){

        for(int i=0; i<dotViewsList.size(); i++){

            if(i == selectItems){
                dotViewsList.get(i).setBackgroundResource(R.drawable.dot_focused);
            }else{
                dotViewsList.get(i).setBackgroundResource(R.drawable.dot_normal);
            }
        }
    }
    private class MyPagerAdapter extends PagerAdapter {
        @Override
        public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
//((ViewPag.er)container).removeView((View)object);
            ((ViewPager)container).removeView(imageViewsList.get(position));
        }
        @Override
        public Object instantiateItem(View container, int position) {
// TODO Auto-generated method stub
            ((ViewPager)container).addView(imageViewsList.get(position));
            return imageViewsList.get(position);		}
        @Override
        public int getCount() {
// TODO Auto-generated method stub
            return imageViewsList.size();		}
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;		}
        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {
        }
        @Override
        public Parcelable saveState() {
            return null;		}
        @Override
        public void startUpdate(View arg0) {
            // TODO Auto-generated method stub
        }
        @Override
        public void finishUpdate(View arg0) {
            // TODO Auto-generated method stub
        }
    }
    private class MyPageChangeListener implements ViewPager.OnPageChangeListener {
        boolean isAutoPlay = false;
        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub
            switch (arg0) {
                case 1:
                    isAutoPlay = false;
                    break;
                case 2:
                    isAutoPlay = true;
                    break;
                case 0:
                    if (mViewPager.getCurrentItem() == mViewPager.getAdapter().getCount() - 1 && !isAutoPlay) {
                        mViewPager.setCurrentItem(0);
                    }
                    else if (mViewPager.getCurrentItem() == 0 && !isAutoPlay) {
                        mViewPager.setCurrentItem(mViewPager.getAdapter().getCount() - 1);
                    }
                    break;
            }
        }
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub
        }
        @Override
        public void onPageSelected(int pos) {
            // TODO Auto-generated method stub
            setImageBackground(pos % imageUris.size());
        }
    }
    private class SlideShowTask implements Runnable{
        @Override
        public void run() {
// TODO Auto-generated method stub
            synchronized (mViewPager) {
                currentItem = (currentItem+1)%imageViewsList.size();
                handler.obtainMessage().sendToTarget();
            }
        }
    }
    @SuppressWarnings("unused")
    private void destoryBitmaps() {
        for (int i = 0; i < imageViewsList.size(); i++) {
            ImageView imageView = imageViewsList.get(i);
            Drawable drawable = imageView.getDrawable();
            if (drawable != null) {
                drawable.setCallback(null);
            }
        }
    }
}


4、MainActivity的佈局:
<example.com.myapplication.SlideShowView
    android:id="@+id/slideshowView"
    android:layout_height="160dp"
    android:layout_width="match_parent"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp" 
    />
5、MainActivity的具體實現程式碼:
private List<String> imageurls;
    private List<String> imageAdUrl;
    private SlideShowView slideShowView;
    slideShowView= (SlideShowView) findViewById(R.id.slideshowView);
        imageurls=new ArrayList<>();
        imageAdUrl=new ArrayList<>();
   imageurls.clear();
   imageAdUrl.clear();
        imageurls.add("http://bdgctest.beidougd.com/Images/Advert/ad_01.png");
        imageurls.add("http://bdgctest.beidougd.com/Images/Advert/ad_02.png");
        imageurls.add("http://bdgctest.beidougd.com/Images/Advert/ad_03.png");
        imageurls.add("http://bdgctest.beidougd.com/Images/Advert/ad_04.png");
        imageAdUrl.add("www.baidu.com");
        imageAdUrl.add("www.sina.com");
        imageAdUrl.add("www.qq.com");
        imageAdUrl.add("www.360.com");
        slideShowView.setImageUris(imageurls,imageAdUrl);//imageurls為網路圖片地址,imageAdUrl為點選相應圖片進行網頁載入的地址


以上載入相應地址可以用迴圈代替,減少程式碼量。要實現下拉重新整理只需在PullToRefresh方法中對資料重新載入。

DisPlayImageOptions可以設定的屬性:

private final int ShowimageResOnLoading;                正在載入時顯示的圖片資源        id  
private final int imageResForEmptyUri;              圖片uri為空時顯示的圖片       id  
private final int ShowimageResOnFail;                   圖片載入失敗顯示的圖片     id  
private final Drawable imageOnLoading;              正在載入時顯示的圖片資源        drawable  
private final Drawable imageForEmptyUri;            圖片uri為空時顯示的圖片       drawable  
private final Drawable imageOnFail;                 圖片載入失敗顯示的圖片     drawable  
private final boolean resetViewBeforeLoading;       載入前是否重置view  
private final boolean cacheInMemory;                是否啟用記憶體快取  
private final boolean cacheOnDisk;                  是否啟用磁碟快取  
private final ImageScaleType imageScaleType;        圖片縮放型別  
private final Options decodingOptions;              BitmapFactory用到的options  
private final int delayBeforeLoading;               延遲多久載入  
private final boolean considerExifParams;           exif引數是否可用  
private final Object extraForDownloader;            額外的下載物件  
private final BitmapProcessor preProcessor;         bitmap載入前的處理  
private final BitmapProcessor postProcessor;        bitmap載入時的處理  
private final BitmapDisplayer displayer;            bitmap顯示  
private final Handler handler;                        
private final boolean isSyncLoading;                是否同步載入圖片(一個接一個的載入)  
從不同地址載入圖片的Url:
String imageUri = "http://site.com/image.png"; // from Web  
String imageUri = "file:///mnt/sdcard/image.png"; // from SD card  
String imageUri = "content://media/external/audio/albumart/13"; // from content provider  
String imageUri = "assets://image.png"; // from assets  
String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)  
ImageLoadingListener監聽中的四個方法:
void onLoadingStarted(String imageUri, View view);  載入開始  
   
void onLoadingFailed(String imageUri, View view, FailReason failReason);  載入失敗   
  
void onLoadingComplete(String imageUri, View view, Bitmap loadedImage); 載入完成   
  
void onLoadingCancelled(String imageUri, View view);  取消載入  
載入進度監聽器ImageLoadingProgressListener:
void onProgressUpdate(String imageUri, View view, int current, int total);  
current:當前完成大小; total:檔案總大小。示例中算進度: 100.0f * current / total,這裡的progressBar的max在layout中設定為100。
滾動時的監聽PauseOnScrollListener:
listView.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), pauseOnScroll, pauseOnFling));
注意事項
  1.上述提到的2個許可權必須加入,否則會出錯<uses-permission android:name="android.permission.INTERNET" />  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
  2.ImageLoaderConfiguration必須配置並且全域性化的初始化這個配置ImageLoader.getInstance().init(config);  否則也會出現錯誤提示
  3.ImageLoader是根據ImageView的height,width確定圖片的寬高。
  4.如果經常出現OOM(別人那邊看到的,覺得很有提的必要)
   ①減少配置之中執行緒池的大小,(.threadPoolSize).推薦1-5;
   ②使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
   ③使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者        try.imageScaleType(ImageScaleType.EXACTLY);
   ④避免使用RoundedBitmapDisplayer.他會建立新的ARGB_8888格式的Bitmap物件;
   ⑤使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();

ImageLoaderConfiguration設定:
 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                context)
                // .memoryCacheExtraOptions(480, 800) // max width, max
                // height,即儲存的每個快取檔案的最大長寬
                // .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75,
                // null) // Can slow ImageLoader, use it carefully (Better don't
                // use it)設定快取的詳細資訊,最好不要設定這個
                .threadPoolSize(3)
                        // 執行緒池內載入的數量
                .discCacheFileNameGenerator(new Md5FileNameGenerator())// 將儲存的時候的URI名稱用MD5   .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                        // .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 *
                        // 1024)) // You can pass your own memory cache
                        // implementation你可以通過自己的記憶體快取實現
                        // .memoryCacheSize(2 * 1024 * 1024)
                        // /.discCacheSize(50 * 1024 * 1024)
               
                        // 加密
                        // .discCacheFileNameGenerator(new
                        // HashCodeFileNameGenerator())//將儲存的時候的URI名稱用HASHCODE加密
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                        // .discCacheFileCount(100) //快取的File數量
                .discCache(new UnlimitedDiscCache(cacheDir))// 自定義快取路徑
                        // .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
                        // .imageDownloader(new BaseImageDownloader(context, 5 * 1000,
                        // 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超時時間
                .writeDebugLogs() // Remove for release app
                .build();
上述
ImageLoaderConfiguration設定根據個人需求進行設定