Android实现一款不错Banner界面广告图片循环轮播

Demo实现的效果图如下:

工程目录如下图:
Android实现一款不错Banner界面广告图片循环轮播_第1张图片
一个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:

"http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <com.skycracks.autoplayingviewpager.AutoPlayingViewPager 
       android:id="@+id/auto_play_viewpager"
       android:layout_width="match_parent"
       android:layout_height="200dp" >
      com.skycracks.autoplayingviewpager.AutoPlayingViewPager>

主方法中运用很简单,只需把接收的对象集合传到自定义的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,这里就不再贴代码,可以通过如下地址下载:
http://blog.csdn.net/stevenhu_223/article/details/45577781
http://download.csdn.net/detail/stevenhu_223/8697903

你可能感兴趣的:(android,移动开发,轮播)