上一篇写的是如何实现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;
}
最终实现效果
最后放上此工程的源码地址