我们在做一些App开发的时候经常会遇到有广告轮播的地方,今天我写了一种方式来供大家参考

1、效果图如下

Android logo 循环移动_android


2、页面布局源码


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="180dp" >

        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="180dp" />

        <LinearLayout
            android:id="@+id/dotLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:gravity="right|bottom"
            android:orientation="horizontal"
            android:background="#a0000000"
            android:padding="8dp" >

            <View
                android:id="@+id/v_dot1"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:background="@mipmap/af_01_icon_graycircle720" />

            <View
                android:id="@+id/v_dot2"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginLeft="5dp"
                android:background="@mipmap/af_01_icon_greencircle720" />
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>


3、class类的源码


import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;
import android.widget.LinearLayout;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 实现广告无限循环滑动
 */
public class MainActivity extends Activity implements View.OnTouchListener {

    private ImageHandler mHandler = new ImageHandler(new WeakReference<MainActivity>(this));
    private ViewPager mViewPager;
    // 自定义轮播图的资源
    private int[] mImageResIds = {R.mipmap.lp_1, R.mipmap.lp_2, R.mipmap.lp_3, R.mipmap.lp_4, R.mipmap.lp_5};
    // 放轮播图片的ImageView 的list
    private List<ImageView> mImageList = new ArrayList<ImageView>();
    // 放圆点的View的list
    private List<View> mDotList = new ArrayList<View>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private void initViews() {
        // 初始化iewPager的内容
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        LinearLayout dotLayout = (LinearLayout) findViewById(R.id.dotLayout);
        dotLayout.removeAllViews();
        for (int i = 0; i < mImageResIds.length; i++) {
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            // view.setTag(mImageResId[i]);
            imageView.setImageResource(mImageResIds[i]);
            mImageList.add(imageView);

            View dotView = new View(MainActivity.this);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getResources().getDimensionPixelSize(R.dimen.dot_width),
                    getResources().getDimensionPixelSize(R.dimen.dot_width));
            params.setMargins(4, 0, 4, 0);
            dotView.setLayoutParams(params);
//          if (i == 0) {
//              dotView.setBackgroundResource(R.mipmap.af_01_icon_greencircle720);
//          } else {
//              dotView.setBackgroundResource(R.mipmap.af_01_icon_graycircle720);
//          }
            dotLayout.addView(dotView);
            mDotList.add(dotView);
        }
        mViewPager.setAdapter(new ImageAdapter(mImageList));
        mViewPager.setOnPageChangeListener(new PageChangeListener());
        mViewPager.setFocusable(true);
        mViewPager.setCurrentItem(Integer.MAX_VALUE / 2);// 默认在中间,使用户看不到边界
        mViewPager.setOnTouchListener(this);
        // 开始轮播效果
        mHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mHandler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
                break;
        }
        return false;
    }

    private class PageChangeListener implements ViewPager.OnPageChangeListener {

        // 配合Adapter的currentItem字段进行设置。
        @Override
        public void onPageSelected(int position) {
            mHandler.sendMessage(Message.obtain(mHandler, ImageHandler.MSG_PAGE_CHANGED, position, 0));
        }

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

        // 覆写该方法实现轮播效果的暂停和恢复
        @Override
        public void onPageScrollStateChanged(int state) {
            switch (state) {
                case ViewPager.SCROLL_STATE_DRAGGING:
                    mHandler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
                    break;
                case ViewPager.SCROLL_STATE_IDLE:
                    mHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
                    break;
                default:
                    break;
            }
        }

    }

    private class ImageAdapter extends PagerAdapter {
        private List<ImageView> viewlist;

        public ImageAdapter(List<ImageView> viewlist) {
            this.viewlist = viewlist;
        }

        @Override
        public int getCount() {
            // 设置成最大,使用户看不到边界
            return Integer.MAX_VALUE;
        }

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

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // Warning:不要在这里调用removeView
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // 对ViewPager页号求模取出View列表中要显示的项
            position %= viewlist.size();
            if (position < 0) {
                position = viewlist.size() + position;
            }
            ImageView view = viewlist.get(position);
            // 如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
            ViewParent vp = view.getParent();
            if (vp != null) {
                ViewGroup parent = (ViewGroup) vp;
                parent.removeView(view);
            }
            container.addView(view);
            // 此处可添加监听事件
            return view;
        }
    }

    private static class ImageHandler extends Handler {
        /**
         * 请求更新显示的View。
         */
        protected static final int MSG_UPDATE_IMAGE = 1;
        /**
         * 请求暂停轮播。
         */
        protected static final int MSG_KEEP_SILENT = 2;
        /**
         * 请求恢复轮播。
         */
        protected static final int MSG_BREAK_SILENT = 3;
        /**
         * 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
         * 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
         * 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
         */
        protected static final int MSG_PAGE_CHANGED = 4;

        // 轮播间隔时间
        protected static final long MSG_DELAY = 3000;

        //         使用弱引用避免Handler泄露.这里的泛型参数可以不是Activity,也可以是Fragment等
        private WeakReference<MainActivity> weakReference;
        private int currentItem = 0;

        // private boolean isOnce = true;

        protected ImageHandler(WeakReference<MainActivity> wk) {
            weakReference = wk;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            final MainActivity mainActivity = weakReference.get();
            if (mainActivity == null) {
                // Activity已经回收,无需再处理UI了
                return;
            }
            // 第一次不删重复的消息
            if (currentItem != 0) {
                // 检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
                if (mainActivity.mHandler.hasMessages(MSG_UPDATE_IMAGE)) {
                    mainActivity.mHandler.removeMessages(MSG_UPDATE_IMAGE);
                }
            }
            switch (msg.what) {
                case MSG_UPDATE_IMAGE:
                    currentItem++;
                    mainActivity.mViewPager.setCurrentItem(currentItem);
                    // 准备下次播放
                    mainActivity.mHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
                    break;
                case MSG_KEEP_SILENT:
                    // 只要不发送消息就暂停了
                    break;
                case MSG_BREAK_SILENT:
                    mainActivity.mHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
                    break;
                case MSG_PAGE_CHANGED:
                    // 记录当前的页号,避免播放的时候页面显示不正确。
                    int position = msg.arg1;
                    int lastIndex = 0;
                    int index = position % mainActivity.mImageList.size();
                    for (int i = 0; i < mainActivity.mDotList.size(); i++) {
                        mainActivity.mDotList.get(i).setBackgroundResource(R.mipmap.af_01_icon_graycircle720);
                    }
                    if (mainActivity.mDotList.get(index) != null) {
                        mainActivity.mDotList.get(index).setBackgroundResource(R.mipmap.af_01_icon_greencircle720);
                    }
                    lastIndex = index;
                    currentItem = position;
                    break;
                default:
                    break;
            }
        }
    }
}



希望对大家有所帮助,不足的地方还请多多指教

源码下载地址: