之前用过三方的轮番图工具库,总想着自己来实现一个,毕竟自己写的东西自己最好控制。
第一个想到的是使用viewpager去实现。看了网上其他人的例子,多多少少会有这样那样的问题,这里我结合他人的例子中的问题写了一个可以完美使用的viewpager;(目前我已经将项目中的轮番图换成我自己写的了)
首先说一下这个轮番图的功能:
1:自动轮番
2:手动轮番,自动轮番停止
3:动态添加和移除数据
4:点击轮番图有点击事件
再说说之前遇到的问题:
1:数据为null的处理
2:数据为1的时候禁止轮番
3:数据为2或者3的时候轮番图出现空白的处理
4:父view为viewpager的时候解决滑动冲突
5,动态添加数据和移除数据的时候出现空白的处理
如果你需要的轮番图是这样的需求,如果你在做轮番图的时候也遇到了类似的问题,那么你可以继续往下看。
效果图就不放了,轮番图想必大家都看过
1:项目结构图
其中:
MyAdapter 为viewpager的适配器
Contant 为存放的常量
DisplayUtil 为转换dp与xp的工具类
FixedSpeedScroller 为重写viewpager的scroller的监听类
TakeTurnsView 为轮番图主类
NoScrollViewPager 为重写的viewpager类
2:Contant 定义常量
public class Contant {
public static boolean isDown;//是否点击了轮番图,默认false
public static boolean isRun;//是否在运行,默认false
}
3:NoScrollViewPager 控制viewpager是否滑动
/**
* 传入onScroll 控制当前 viewpager
*/
public class NoScrollViewPager extends ViewPager {
private boolean noScroll = false;//false可以滑动;true则不能滑动
private Handler handler;//自动轮番的消息机制
public NoScrollViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public NoScrollViewPager(Context context) {
super(context);
}
public void setNoScroll(boolean noScroll) {
this.noScroll = noScroll;
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
}
@Override
public boolean onTouchEvent(MotionEvent arg0) {
//如果不能轮番,则直接将touch事件向上传递
if (noScroll)
return false;
else
return super.onTouchEvent(arg0);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
//如果不能轮番,则直接将touch事件向上传递
if (noScroll)
return false;
else
return super.onInterceptTouchEvent(arg0);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//如果不能轮番,则自动轮番的消息不再发送
if (noScroll)
return super.dispatchTouchEvent(ev);
int action = ev.getAction();
if (action == MotionEvent.ACTION_DOWN) {
Contant.isRun = false;//手指按下,则不能自动轮番
Contant.isDown = true;//按下状态为true
if (handler != null)
handler.removeCallbacksAndMessages(null);//清空消息队列
} else if (action == MotionEvent.ACTION_UP) {
Contant.isRun = true;//手指抬起,自动轮番开始
Contant.isDown = false;//按下状态为false
if (handler != null) {
handler.removeCallbacksAndMessages(null);//清空消息队列
handler.sendEmptyMessage(1);//重新发送轮番的指令
}
}
return super.dispatchTouchEvent(ev);
}
public void setInfinateAdapter(Handler handler, MyAdapter adapter) {
this.handler = handler;
setAdapter(adapter);
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
super.setCurrentItem(item, smoothScroll);
}
@Override
public void setCurrentItem(int item) {
super.setCurrentItem(item);
}
}
4,FixedSpeedScroller 重新设置viewpager的轮番时间
/**
* Created by 浩 on 2016/8/31.
* 重写scroller来控制viewpager的滑动速度
*/
public class FixedSpeedScroller extends Scroller {
private int mDuration = 400;//默认的轮番时间为400ms
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead