要實現自定義ViewPager,就要自己重寫ScollerView,寫一個繼承ViewGroup的自定義控件。
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
public class MyScrollView extends ViewGroup {
//解析手勢的工具
private GestureDetector detector;
//這是一個用於計算
private Scroller myScoller;
//記錄down事件時的Y座標
private int startY;
//記錄當前的id值
private int currentId;
private Context context;
//記錄是否是快速滑動
private boolean isFling;
//重寫構造方法
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.context = context;
initView();
}
private void initView() {
// TODO Auto-generated method stub
myScoller = new Scroller(context);
detector = new GestureDetector(new OnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
//滑動事件
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
scrollBy(0, (int) distanceY);
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) {
isFling = true;
if (velocityY < 0 && currentId > 0) {
currentId--;
} else if (velocityY > 0 && currentId < getChildCount() - 1) {
currentId++;
}
moveToDest(currentId);
return false;
}
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
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++) {
View v = getChildAt(i);
v.layout(0, -getHeight() * i, getWidth(), getHeight() * (1 - i));
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
detector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
//UP事件發生時,先判斷是否是快速滑動,若是快速滑動,則GestureDetector會去處理
if (!isFling) {
//若不是快速滑動,則判斷滑動到了哪裏,向上滑動,或向下滑動
int disY = (int) (event.getY() - startY);
if (disY > getHeight() / 2) {
currentId++;
} else if (disY < -getHeight() / 2) {
currentId--;
}
moveToDest(currentId);
}
break;
}
return true;
}
/**
* 滑動到目標ID的方法
* @param id
*/
private void moveToDest(int id) {
// TODO Auto-generated method stub
id = id >= 0 ? id : 0;
id = id < getChildCount() ? id : (getChildCount() - 1);
int disY = -getScrollY() - id * getHeight();
//給 myScoller設置初始座標和目標座標
myScoller.startScroll(0, getScrollY(), 0, disY);
currentId = id;
invalidate();
}
/**
* ViewGroup調用invalidate()方法時,會調用該方法
*/
@Override
public void computeScroll() {
// myScoller會固定時間計算當前位置
if (myScoller.computeScrollOffset()) {
scrollTo(0, myScoller.getCurrY());
//invalidate方法會重複調用computeScroll方法,直到到達myScoller的目標座標爲止
invalidate();
}
super.computeScroll();
}
}
然後將需要添加的視圖利用addView方法,添加到MyScollerView中就可以了。