ViewPager实现图片无限轮播(下)

上一篇写的是如何实现viewPager无限轮播效果(手动滑动)
以及解释了ViewPager在进行显示View时容易出现的Bug

在最后演示了

1.底部指示器效果
2.自动轮播效果

这一篇就来写写上面的两个功能是如何实现的

添加底部指示器效果
这个效果是当图片滑动的时候底部的小圆圈也会随着滑动而改变

这里写图片描述

1.设置指示器布局

在ViewPager的底部设置一个线性布局,线性布局中添加三个ImageView,就是三个小圆圈的样子

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="140dp">
        <android.support.v4.view.ViewPager
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:id="@+id/main_view_pager"
            ></android.support.v4.view.ViewPager>
        <!--图片轮播指示器-->
        <LinearLayout
            android:id="@+id/main_ll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="20dp"
            ></LinearLayout>    
    </RelativeLayout>>

ViewPager和线性布局的指示器是重合的,所以两个的根布局为 RelativeLayout
因为也许我们并不知道我们的轮播器中需要轮播几张图片,所以线性布局的小圆圈是需要动态添加的

但是可以先将小圆圈的样子做出来(这个圆圈是自己画出来的)

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="10dp" android:layout_height="10dp"
    android:background="@drawable/banner_point"
    android:layout_margin="10dp"
    >
</ImageView>

上面是向线性布局动态添加的小圆圈的样子,是一个ImageView

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
    <shape android:shape="oval">
        <solid
            android:color="@android:color/holo_red_light"/>
        <stroke
            android:width="1px"
            android:color="@android:color/black"
            />
    </shape>
</item>
    <item android:state_selected="false">
        <shape android:shape="oval">
            <solid
                android:color="@android:color/white"/>
            <stroke
                android:width="1px"
                android:color="@android:color/black"
                />
        </shape>
    </item>
</selector>

select是我对小圆圈样子的绘制,不懂select的可以直接将这些复制到drawable目录下,我取名为
banner_point.xml

这样指示器的位置和小圆圈显示的样子就写完了

2.将小圆圈动态添加到线性布局当中

private void initPointData() {
        //images是一个数组,放置轮播的图片资源地址
        int len = images.length;
        //判断一共几个数据就添加几个小圆点
        for (int i = 0; i < len; i++) {
        //得到小圆点对象
            ImageView imageView = (ImageView) LayoutInflater.from(SecondActivity.this).inflate(R.layout.view_banner_point, null);
            imageView.setImageResource(R.drawable.banner_point);
            //设置添加ImageView的宽高(像素) 在xml文件中虽然定义过但是不出现效果,需要在java文件中重新定义
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(20, 20);
            //设置每个小圆圈的左右间距,会更加美观
            lp.leftMargin = 10;
            lp.rightMargin = 10;
            imageView.setLayoutParams(lp);
            //将这个小圆圈View添加到线性布局当中(ll为线性布局的对象)
            ll.addView(imageView);
        }

    }

布局添加完了,下面就要添加对ViewPager滑动改变的监听,并改变小圆圈的颜色

3.根据滑动的改变,改变小圆圈的颜色

根据当前显示的position,改变小圆圈颜色的方法

//选中某一个指示器
    private void setPoint(int position) {
        int len = images.length;
        for (int i = 0; i < len; i++) {
            //选择线性布局中第i个小圆圈
            ImageView imageView = (ImageView) ll.getChildAt(i);
            //如果选择的小圆圈和当前显示的View的position是吻合的
            if (i ==position) {
                //将第i个圆圈设成被选中状态
                imageView.setSelected(true);
            } else {
                imageView.setSelected(false);
            }
        }
    }

在ViewPager的页面监听事件中,根据页面的切换,更改小圆圈的颜色

//viewPager的监听事件
    private void initEvent() {
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            //页面在滚动,页面的滑动信息
            //positionOffset 滑动的百分比  positionOffsetPixels滑动的像素点
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                //修改小圆点显示的位置
                setPoint(position % images.length);

            }
            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

通过上面的步骤就可以实现手动滑动ViewPager时,指示器的改变

自动轮播图片效果

实现每两秒钟图片自动切换

1.开启子线程,睡眠时间为两秒,两秒之后切换ViewPager
2.实例化一个Handler,在handler中更新UI

1.开启子线程,每隔两秒钟通知handler更新UI

//两秒钟切换一次界面
    private class TimerThread extends Thread{
        @Override
        public void run() {
            super.run();
            //判断此界面是否存在
            while (isAlive){
                try {
                    Thread.sleep(1000*2);
                    if (isAlive) {
                    //判断线程是否停止工作
                        if (isWorking) {
                            handler.sendEmptyMessage(1);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

2.实例化Handler 更新UI

private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what==1){
                //切换到下一页
                viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
            }
        }
    };

开启线程

new TimerThread().start();

上面有两个变量

isAlive
因为此子线程是一个无限自动轮播,无限循环,当退出此界面时,为了防止内存泄漏,要将此线程中的while无限循环结束
isWorking
当手指进行滑动的时候线程的自动轮播要停止,防止出现手指滑动距离小(不足以翻页时),子线程就将ViewPager自动轮播到下一页

下面是当程序退出时,while循环也要关闭,子线程停止操作

@Override
    protected void onDestroy() {
        super.onDestroy();
        isAlive=false;
    }

下面是ViewPager监听事件(initEvent()方法)中的判断用户点击状态的事件

@Override
            public void onPageScrollStateChanged(int state) {
                //处于空闲状态,线程工作
                if(state==ViewPager.SCROLL_STATE_IDLE){
                    isWorking=true;
                    //手动进行拖拽状态
                }else if(state==ViewPager.SCROLL_STATE_DRAGGING){
                    //线程停止轮播(并没有将线程杀死)
                    isWorking=false;
                }

最终实现效果
这里写图片描述

最后放上此工程的源码地址

https://github.com/XuDaHaoRen/ViewPagerDemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值