public class MyViewPager extends ViewGroup {
private int page;//当前页的索引
private GestureDetector detector;//手势探测
private Context context;//控件创立的上下文
private MyScroller scroller;//缓慢页面切换帮助类,
private boolean isFling;//用于判断
private MyViewOnPageChangedListener listener;//页面变化监听事件
/**
*创建两个参数的构造函数,用于在布局文件中使用。在构造函数中,调用initView()方法初始化控件,建立GestureDetector对象,响应屏幕触摸事件。
*/
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
// TODO Auto-generated constructor stub
initView();
}
public void initView(){
scroller=new MyScroller();
detector=new GestureDetector(context,new GestureDetector.OnGestureListener(){
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
/**
* 图片缓慢滑动效果
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
scrollBy((int)distanceX,0);
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
/**
* 图片快速滑动切换
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
// TODO Auto-generated method stub
isFling=true;
if(velocityX<0&&page<getChildCount()-1){
page++;
}else if(velocityX>0&&page>0){
page--;
}
moveToDes(page);
return false;
}});
}
/** * 设置子view的布局,使其按照父控件的大小沿着水平方向展开 */
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
for(int i=0;i<getChildCount();i++){
getChildAt(i).layout(i*getWidth(),0,getWidth()+i*getWidth(),getHeight());
}
}
/** * 重载onTouchEvent方法,设置page值,当手指滑动超过二分之一屏幕宽度时,切换到下一个或上一个页面, * 当不足二分之一屏幕宽度时,页面不切换 */
private int firstPosition;//记录手指按下时的位置
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
detector.onTouchEvent(event);
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
firstPosition=(int)event.getX();
break;
case MotionEvent.ACTION_UP:
/**
* 用isFling区分缓慢移动和快速移动
*/
if(!isFling){
if(event.getX()-firstPosition>getWidth()/2){
page=page-1;
}else if(firstPosition-event.getX()>getWidth()/2){
page=page+1;
}
moveToDes(page);
break;
}
isFling=false;
}
return true;
}
/**
* 使其移动到page相应的页面
* @param page
*/
public void moveToDes(int page) {
// TODO Auto-generated method stub
if(page<=0){
page=0;
}
if(page>=getChildCount()-1){
page=getChildCount()-1;
}
/**
* 迅速页面切换
*/
//scrollTo(page*getWidth(), 0);
/**
* 添加页面变化监听,监听事件放入常常调用的方法里,显示事件的常常调用
*/
listener.onPageChanged(page);
//缓慢页面切换动画
int distance=page*getWidth()-getScrollX();
scroller.startScroll(getScrollX(), distance);
invalidate();//刷新页面,重画,而且从新执行computeScroll()
}
//重复执行该方法,实现动画效果
@Override
public void computeScroll() {
// TODO Auto-generated method stub
super.computeScroll();
if(scroller.isScrolling()){
scrollTo(scroller.getCurrentX(), 0);
invalidate();
}
}
/**
* 设置监听事件方法
* @param listener
*/
public void setPageChangedListener(MyViewOnPageChangedListener listener){
this.listener=listener;
}
/**
* 监听事件接口,监听页面变化
* @author Charles
*
*/
interface MyViewOnPageChangedListener{
public void onPageChanged(int page);
}
}