Android ViewPager 实现滑动跟定时循环连播外加底部小红点指示器

本文的内容通过标题可以看得出,是通过viewpager来滑动图片,同时还可以手动设置定时时间来实现自动播放,图片滑动的同时小红点指示器会跟随变化。先上效果图
这里写图片描述
上代码

1.Handler主要来处理手动跟自动之间的切换


public class MyHandler extends Handler {
    private ViewPager viewPager;
    /**
     * 请求更新显示的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 = 1000;


    private int currentItem = 0;

    //        protected //ImageHandler(WeakReference<MainActivity> wk){
//            weakReference = wk;
//        }
    protected ImageHandler(ViewPager viewPager) {
        this.viewPager = viewPager;
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        Log.d("", "receive message " + msg.what);

        //检查消息队列并移除未发送的消息,主要是避免在复杂环境下消息出现重复等问题。
        if (hasMessages(MSG_UPDATE_IMAGE)) {
            removeMessages(MSG_UPDATE_IMAGE);
        }
        switch (msg.what) {
            case MSG_UPDATE_IMAGE:
                currentItem++;
                viewPager.setCurrentItem(currentItem);
                //准备下次播放  
                sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
                break;
            case MSG_KEEP_SILENT:
                //只要不发送消息就暂停了  
                break;
            case MSG_BREAK_SILENT:
                sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
                break;
            case MSG_PAGE_CHANGED:
                //记录当前的页号,避免播放的时候页面显示不正确。  
                currentItem = msg.arg1;
                break;
            default:
                break;
        }
    }
}


2.MainActivity的逻辑



public class MainActivity extends Activity {
    private ArrayList<ImageView> imageViews;
    private int[] imageResId; // 图片ID
    private static final String LOG_TAG = "MainActivity";
    private MyHandler handler;
    private ViewPager viewPager;

    private LinearLayout mLinearLayout;
    private View mView;
    private int diatance;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化iewPager的内容
        viewPager = (ViewPager) findViewById(R.id.vp_pic);
        mLinearLayout = (LinearLayout) findViewById(R.id.ll_points);

        mView = findViewById(R.id.v_redpoint);

        handler = new ImageHandler(viewPager);
        initData();
        viewPager.setAdapter(new ImageAdapter(imageViews));
        /**
         * 当底部红色小圆点加载完成时测出两个小灰点的距离,便于计算后面小红点动态移动的距离
         */
        mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                diatance = mLinearLayout.getChildAt(1).getLeft() - mLinearLayout.getChildAt(0).getLeft();

            }
        });

        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

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

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //测出页面滚动时小红点移动的距离,并通过setLayoutParams(params)不断更新其位置
                position = position % imageViews.size();
                float leftMargin = diatance * (position + positionOffset);
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams();
                params.leftMargin = Math.round(leftMargin);
                mView.setLayoutParams(params);


            }

            //覆写该方法实现轮播效果的暂停和恢复
            @Override
            public void onPageScrollStateChanged(int arg0) {
                switch (arg0) {
                    case ViewPager.SCROLL_STATE_DRAGGING:
                        handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
                        break;
                    case ViewPager.SCROLL_STATE_IDLE:
                        handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
                        break;
                    default:
                        break;
                }
            }
        });
        viewPager.setCurrentItem(0);//默认在中间,使用户看不到边界
        //开始轮播效果
        handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
    }


    private void initData() {
        imageViews = new ArrayList();
        imageResId = new int[]{R.drawable.eo, R.drawable.eopard,
                R.drawable.eo, R.drawable.eopard};
        for (int i = 0; i < imageResId.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(imageResId[i]);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews.add(imageView);

            //添加底部小黄点
            View v = new View(getApplicationContext());
            v.setBackgroundResource(R.drawable.yellow_circle);
            //指定其大小
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
            if (i != 0)
                params.leftMargin = 20;
            v.setLayoutParams(params);
            mLinearLayout.addView(v);

        }
    }
}

3.资源文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

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


    <RelativeLayout
        android:id="@+id/rl_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="45dip">

        <LinearLayout
            android:id="@+id/ll_points"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"></LinearLayout>

        <View
            android:id="@+id/v_redpoint"
            android:layout_width="10dip"
            android:layout_height="10dip"
            android:background="@drawable/red_circle" />
    </RelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#ff0000" />

    <corners android:radius="5dip" />

</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <solid android:color="#effe33" />

    <corners android:radius="5dip" />

</shape>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值