Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android實現一款不錯Banner界面廣告圖片循環輪播

Android實現一款不錯Banner界面廣告圖片循環輪播

編輯:關於Android編程

Demo實現的效果圖如下:
這裡寫圖片描述
工程目錄如下圖:
這裡寫圖片描述
一個Application,一個實體類,一個Activity,另一個是自定義的AutoPlayingViewPager繼承FrameLayout。
首先看一下自定義的AutoPlayingViewPager,功能都在這裡實現。采用了第三方圖片加載框架:universal_image_loader;

package com.skycracks.autoplayingviewpager;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.nostra13.universalimageloader.core.ImageLoader;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;



/**
 * 創建時間: 2016年1月10日 下午3:43:22

 * 版本: [v1.0]

 * 類描述: 實現ViewPager輪播圖

 * 使用了ImageLoader 對圖片進行加載,所以使用前必須初始化ImageLoader

 * stopPlaying() 當輪播所在頁面不在頂棧時,有必要停止定時並且釋放資源

 * startPlaying() 當再次恢復時調用

 *
 */
public class AutoPlayingViewPager extends FrameLayout {

    private final static String TAG = "AutoPlayingViewPager";
    /**
     * 輪播圖圖片數量
     */
    private int IMAGE_COUNT;
    /**
     * 自動輪播的時間間隔
     */
    private final static int TIME_INTERVAL = 5;
    /**
     * 切換圖片過度時間
     */
    private int swapDuration = 1000;
    /**
     * 默認圖片資源(本地圖片資源Id)
     */
    private int [] defaultIds = new int[] {
            R.drawable.image01,R.drawable.image02,
            R.drawable.image03,R.drawable.image04,R.drawable.image05};
    /**
     * 默認圖片資源(圖片URL地址)
     */
    private String [] defaultUrl = new String[] {
            "http://g.hiphotos.baidu.com/imgad/pic/item/a8773912b31bb051be533b24317adab44aede043.jpg",
            "http://g.hiphotos.baidu.com/imgad/pic/item/c75c10385343fbf22c362d2fb77eca8065388fa0.jpg",
            "http://liaoning.sinaimg.cn/2014/1111/U10435P1195DT20141111220802.jpg",
            "http://photocdn.sohu.com/20151124/mp43786429_1448294862260_4.jpeg",
            "http://h.hiphotos.baidu.com/image/pic/item/faedab64034f78f0b00507c97e310a55b3191cf9.jpg" };

    private String [] defaultTitle = new String [] {
        "今晚打老虎","今晚打松鼠","今晚打LOL","今晚打DOTA1","今晚打DOTA2"};
    /**
     * 自定義輪播圖資源
     */
    private List mAutoPlayInfoList;
    /**
     * 放圓點的View的list
     */
    private List dotViewsList;
    /**
     * 輪播容器
     */
    private ViewPager mViewPager;
    /**
     * 當前輪播頁
     */
    private int currentItem = 0;
    /**
     * 定時器對象
     */
    private ScheduledExecutorService scheduledExecutorService;

    private Context mContext;

    private LayoutInflater mInflate;
    /**
     * ViewPageItem點擊回調接口
     */
    private OnPageItemClickListener onPageItemClickListener;

    public void setOnPageItemClickListener(OnPageItemClickListener onPageItemClickListener){
        this.onPageItemClickListener = onPageItemClickListener;
    }

    public interface OnPageItemClickListener{
        /**
         * ViewPageItem點擊事件回調
         */
        void onPageItemClick(int position, String adLink);
    }

    /**
     * 消息處理器、設置當前顯示頁
     */
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            mViewPager.setCurrentItem(currentItem);
        }
    };

    public AutoPlayingViewPager(Context context) {
        this(context, null);
    }

    public AutoPlayingViewPager(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AutoPlayingViewPager(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        initData();
    }

    /**
     * 通過本地圖片資源Id獲得默認的數據
     */
    private List getImageIdAutoPlayInfoList(int [] imageIds){
        List autoPlayInfoList = new ArrayList();
        for(int i = 0 ; i < imageIds.length ; i ++){
            AutoPlayInfo autoPlayInfo = new AutoPlayInfo();
            autoPlayInfo.setImageId(imageIds[i]);
            autoPlayInfoList.add(autoPlayInfo);
        }
        return autoPlayInfoList;
    }

    /**
     * 通過圖片URL地址獲得默認的數據
     */
    private List getDefaultUrlAutoPlayInfoList(){
        List autoPlayInfoList = new ArrayList();
        for(int i = 0 ; i < defaultUrl.length ; i ++){
            AutoPlayInfo autoPlayInfo = new AutoPlayInfo();
            autoPlayInfo.setImageUrl(defaultUrl[i]);
            autoPlayInfo.setAdLinks("http://m.baidu.com");
            autoPlayInfo.setTitle(defaultTitle[i]);
            autoPlayInfoList.add(autoPlayInfo);
        }
        return autoPlayInfoList;
    }

    /**
     * 初始化
     * @param imageIds 需要加載的圖片Id,根據傳入數量動態創建容器。
     * @return
     */
    public AutoPlayingViewPager initialize(int [] imageIds) {
        if (imageIds != null && imageIds.length != 0) {
            mAutoPlayInfoList = getImageIdAutoPlayInfoList(imageIds);
        } else {//沒有數據使用默認的圖片資源
            mAutoPlayInfoList = getImageIdAutoPlayInfoList(defaultIds);
        }
        IMAGE_COUNT = mAutoPlayInfoList.size();
        return this;
    }

    /**
     * 初始化
     * 
     * @param imageUrls 需要加載的圖片地址,根據傳入數量動態創建容器。
     * @return
     */
    public AutoPlayingViewPager initialize(List autoPlayInfoList) {
        if (autoPlayInfoList != null && !autoPlayInfoList.isEmpty()) {
            mAutoPlayInfoList = autoPlayInfoList;
        } else {//沒有數據使用默認的圖片資源
            mAutoPlayInfoList = getDefaultUrlAutoPlayInfoList();
        }
        IMAGE_COUNT = mAutoPlayInfoList.size();
        return this;
    }

    /**
     * 設置圖片之間自動切換時間
     * 
     * @param duration
     *            切換時間
     * @return
     */
    public AutoPlayingViewPager setSwapDuration(int duration) {
        this.swapDuration = duration;
        return this;
    }

    /**
     * 開始輪播圖切換 輪播之前必須調initialize()及build()
     */
    public void startPlaying() {
            scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
            scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 1,
                TIME_INTERVAL, TimeUnit.SECONDS);
    }

    /**
     * 停止輪播釋放資源
     */
    public void stopPlaying() {
        scheduledExecutorService.shutdown();
    }

    /**
     * 初始化相關Data
     */
    private void initData() {
        dotViewsList = new ArrayList();
    }

    /**
     * 初始化Views 及組件UI
     */
    public void build() {
        if (mAutoPlayInfoList == null || mAutoPlayInfoList.isEmpty()) {
            Log.d(TAG, "init image fail ");
            return;
        }
        mInflate = LayoutInflater.from(mContext);
        mInflate.inflate(R.layout.view_layout_slideshow,this, true);
        LinearLayout dotLayout = (LinearLayout) findViewById(R.id.dotLayout);
        dotLayout.removeAllViews();// 清除布局中的子視圖,下面使用代碼動態添加與圖片對應的圓點

        // 熱點個數與圖片數量相等
        for (int i = 0; i < IMAGE_COUNT; i++) {
            ImageView dotView = new ImageView(mContext);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            params.leftMargin = 4;
            params.rightMargin = 4;
            dotLayout.addView(dotView, params);
            dotViewsList.add(dotView);
        }

        mViewPager = (ViewPager) findViewById(R.id.viewPager);
        setViewPagerScrollSpeed();
        mViewPager.setFocusable(true);
        mViewPager.setOffscreenPageLimit(2);// 設置緩存頁面,當前頁面的相鄰N各頁面都會被緩存
        mViewPager.setAdapter(new AutoPlayingPagerAdapter());
        AutoPlayingPageChangeListener mPageChangeListener = new AutoPlayingPageChangeListener();
        mViewPager.addOnPageChangeListener(mPageChangeListener);
    }

    /**
     * 填充ViewPager的頁面適配器
     */
    private class AutoPlayingPagerAdapter extends PagerAdapter {

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            final AutoPlayInfo autoPlayInfo = mAutoPlayInfoList.get(position % IMAGE_COUNT);
            View view = mInflate.inflate(R.layout.item_label_auto_play_viewpager, null);
            ImageView imageView = (ImageView) view.findViewById(R.id.img_item_auto_play);
            TextView labelTitle = (TextView) view.findViewById(R.id.tv_item_label_title);
        /*  if(!TextUtils.isEmpty(autoPlayInfo.getAdLinks())){//有鏈接時才添加監聽

            }*/
            view.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    onPageItemClickListener.onPageItemClick(position % IMAGE_COUNT,autoPlayInfo.getAdLinks());
                }
            });
            if(!TextUtils.isEmpty(autoPlayInfo.getImageUrl())){//通過URL時使用ImageLoader加載圖片
                ImageLoader.getInstance().displayImage(autoPlayInfo.getImageUrl(),imageView);
            }else if(autoPlayInfo.getImageId() != 0){//本地圖片時直接設置
                imageView.setImageResource(autoPlayInfo.getImageId());
            }
            if(!TextUtils.isEmpty(autoPlayInfo.getTitle())){//有標題數據才顯示
                labelTitle.setText(autoPlayInfo.getTitle());
            }else{//沒有標題數據不顯示文本透明背景
                labelTitle.setBackgroundDrawable(null);
            }
            container.addView(view);
            return view;
        }

        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }
    }


    /**
     * ViewPager的監聽器 當ViewPager中頁面的狀態發生改變時調用
     * 
     */
    private class AutoPlayingPageChangeListener implements OnPageChangeListener {
        // boolean isChange = false;

        @Override
        public void onPageScrollStateChanged(int arg0) {
            switch (arg0) {
            case 1:// 手勢滑動,空閒中
                // isChange = false;
                break;
            case 2:// 界面切換中
                // isChange = true;
                break;
            case 0:// 滑動結束,即切換完畢或者加載完畢

                break;
            }
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageSelected(int pos) {
            currentItem = pos;
            int p = pos % IMAGE_COUNT;
            for (int i = 0; i < dotViewsList.size(); i++) {
                if (i == p) {
                    dotViewsList.get(p).setBackgroundResource(
                            R.drawable.icon_cricle_check);
                } else {
                    dotViewsList.get(i).setBackgroundResource(
                            R.drawable.icon_cricle_uncheck);
                }
            }
        }
    }

    /**
     * 執行輪播圖切換任務
     * 
     */
    boolean isLR = false;

    private class SlideShowTask implements Runnable {
        @Override
        public void run() {
            synchronized (mViewPager) {
                currentItem++;
                handler.obtainMessage().sendToTarget();
            }
        }
    }
    /**
     * 使用反射往ViewPager中設置新的Scroller對象 覆蓋默認的setCurrentItem切換時間
     */
    private void setViewPagerScrollSpeed() {
        try {
            Field mScroller = null;
            mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            FixedSpeedScroller scroller = new FixedSpeedScroller(
                    mViewPager.getContext());
            mScroller.set(mViewPager, scroller);
        } catch (NoSuchFieldException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
    }

    class FixedSpeedScroller extends Scroller {
        public FixedSpeedScroller(Context context) {
            super(context);
        }

        public FixedSpeedScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        public FixedSpeedScroller(Context context, Interpolator interpolator,
                boolean flywheel) {
            super(context, interpolator, flywheel);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy,
                int duration) {
            super.startScroll(startX, startY, dx, dy, swapDuration);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            super.startScroll(startX, startY, dx, dy, swapDuration);
        }
    }
}

當然想用上ImageLoad而必須在Application裡面注冊一下:

    @Override
    public void onCreate() {
        super.onCreate();
        initImageLoader();
    }

    /**
     * 初始化UIL,這裡初始化以後,就不在初始化了
     */
    public void initImageLoader() {
        DisplayImageOptions.Builder options = new DisplayImageOptions.Builder()
                .cacheInMemory(true)// 內存緩存
                .cacheOnDisk(true)// 磁盤緩存
                .showImageOnFail(R.drawable.ic_faile)//加載失敗顯示的圖片
                .considerExifParams(true)// 是否考慮EXIF信息,比如拍照方向
                .displayer(new FadeInBitmapDisplayer(300));//淡入動畫
        ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(getApplicationContext());
        // 取消緩存多張尺寸不同的同一張圖片
        config.denyCacheImageMultipleSizesInMemory();
        // 設置顯示選項
        config.defaultDisplayImageOptions(options.build());
        // 生成緩存文件的生成器,保證唯一的文件名,可以不設置,默認使用hash算法,也是可以保證不重名的
        config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
        // 磁盤緩存大小
        config.diskCacheSize(100 * 1024 * 1024); // 100 MB
        // 內存緩存大小
        config.memoryCacheSize((int) (Runtime.getRuntime().freeMemory() / 4));
        // 任務處理順序,默認是FIFO 先進先出, LIFO 後進先出
        config.tasksProcessingOrder(QueueProcessingType.LIFO);
        // 打印調試日志
        config.writeDebugLogs(); // Remove for release app
        ImageLoader.getInstance().init(config.build());
    }

最關鍵的就是調用:
布局直接調用自定義的ViewPager:



    
      

主方法中運用很簡單,只需把接收的對象集合傳到自定義的AutoPlayingViewPager。
看代碼:

package com.skycracks.autoplayingviewpager;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.skycracks.autoplayingviewpager.AutoPlayingViewPager.OnPageItemClickListener;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private AutoPlayingViewPager mAutoPlayingViewPager;
    /**
     * 模擬網絡請求獲取的圖片URL
     */
    private String [] imageUrl = new String[] {
            "http://g.hiphotos.baidu.com/image/pic/item/d0c8a786c9177f3e117088eb75cf3bc79e3d568b.jpg",
            "http://upload.cebnet.com.cn/2014/1217/1418776413348.jpg",
            "http://n.sinaimg.cn/transform/20150917/7DDk-fxhytwp5363222.jpg",
            "http://n.sinaimg.cn/transform/20151019/YtA_-fxivsce6931363.jpg"
            };

    private String [] imageTitle = new String [] {
            "趙麗穎","高圓圓","王鷗","唐嫣"};

    private List mAutoPlayInfoList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAutoPlayingViewPager = (AutoPlayingViewPager) findViewById(R.id.auto_play_viewpager);
        mAutoPlayInfoList=new ArrayList<>();
        for(int i = 0 ; i < imageUrl.length ; i ++){
        //把模擬的數據添加到集合裡面
            AutoPlayInfo autoPlayInfo = new AutoPlayInfo();
            autoPlayInfo.setImageUrl(imageUrl[i]);
            autoPlayInfo.setAdLinks("");
            autoPlayInfo.setTitle(imageTitle[i]);
            mAutoPlayInfoList.add(autoPlayInfo);
        }
//通過這個方法把集合傳進去,並設置圖片的點擊事件,可以做跳轉
        mAutoPlayingViewPager.initialize(mAutoPlayInfoList).build();
        mAutoPlayingViewPager.setOnPageItemClickListener(onPageItemClickListener);
    }

    private OnPageItemClickListener onPageItemClickListener = new OnPageItemClickListener() {

        @Override
        public void onPageItemClick(int position, String adLink) {

            Toast.makeText(MainActivity.this,"第"+position,Toast.LENGTH_LONG).show();
        }

    };


    @Override
    public void onStart() {   //當Activity onRestart();還要執行,
        //沒有數據時不執行startPlaying,避免執行幾次導致輪播混亂
        if(mAutoPlayInfoList != null && !mAutoPlayInfoList.isEmpty()){
            mAutoPlayingViewPager.startPlaying();
        }
        super.onResume();
    }

    @Override
    public void onPause() {
        mAutoPlayingViewPager.stopPlaying();
        super.onPause();
    }
}

最後幾個就是實體類:

public class AutoPlayInfo {
    //輪播圖片URL
    private String imageUrl;
    //輪播本地圖片資源Id
    private int imageId;
    //鏈接
    private String adLinks;
    //圖片對應的標題
    private String title;


    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }

    public String getAdLinks() {
        return adLinks;
    }

    public void setAdLinks(String adLinks) {
        this.adLinks = adLinks;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

另外,還有一種通過自定義ViewPager實現和本博文相同效果的廣告界面Demo,這裡就不再貼代碼。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved