继承Viewgroup类
//借用了别人的类有些乱码,见谅~~
public class ScrollViewGroup extends ViewGroup {
private static final int TOUCH_STATE_REST = 0;
private static final int TOUCH_STATE_SCROLLING = 1;
private static final int SNAP_VELOCITY = 400;//滑动视图的??
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private int mCurScreen;//当前界面
private int mDefaultScreen = 0;//默认界面
private int page = 0;//视图页数
private int mTouchState = TOUCH_STATE_REST;//设置触发状?
private int mTouchSlop;//触发移动的像素距?
private float mLastMotionX;//手势滑动卷轴的x?
private PageListener pageListener;//页码监听
public ScrollViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ScrollViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScroller = new Scroller(context);
mCurScreen = mDefaultScreen;//默认设置显示第一个VIEW
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childLeft = 0;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View childView = getChildAt(i);
if (childView.getVisibility() != View.GONE) {
final int childWidth = childView.getMeasuredWidth();
childView.layout(childLeft, 0, childLeft + childWidth, childView.getMeasuredHeight());
childLeft += childWidth;
Log.v("init", "l="+l+" t="+t+" r="+r+" b="+b);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("ScrollLayout only canmCurScreen run at EXACTLY mode!");
}
/**
* wrap_content 传进去的是AT_MOST 固定??或fill_parent 传入的模式是EXACTLY
*/
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
//throw new IllegalStateException("ScrollLayout only can run at EXACTLY mode!");
}
// The children are given the same width and height as the scrollLayout
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
scrollTo(mCurScreen * width, 0);
}
/**
* According to the position of current layout scroll to the destination
* page.
*/
private void snapToDestination() {
final int screenWidth = getWidth();
final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
snapToScreen(destScreen);
}
public void snapToScreen(int whichScreen) {
// get the valid layout page
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
if (getScrollX() != (whichScreen * getWidth())) {
final int delta = whichScreen * getWidth() - getScrollX();
//这里使用scroll是因为在View滑动的过程中获取滑动scrollX和scrollY
mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);
mCurScreen = whichScreen;
invalidate(); // Redraw the layout刷新view,调用viewGroup的computeScroll()进行view的滑?
}
}
public void setToScreen(int whichScreen) {
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
mCurScreen = whichScreen;
scrollTo(whichScreen * getWidth(), 0);
}
/**
* 获得当前页码
*/
public int getCurScreen() {
return mCurScreen<0?0:mCurScreen;
}
/**
* 当滑动后的当前页??*/
public int getPage() {
return mCurScreen<0?0:mCurScreen;
}
@Override
public void computeScroll()
{
//scroll有滑动偏移量?
if (mScroller.computeScrollOffset())
{
//获取scroll的滑动当前坐标移动View
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
final int action = event.getAction();
final float x = event.getX();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) (mLastMotionX - x);
mLastMotionX = x;
scrollBy(deltaX, 0);
break;
case MotionEvent.ACTION_UP:
final VelocityTracker velocityTracker = mVelocityTracker;
//使用之前先要设置滑动速率的单位,1000代表1秒运动了多少个像素,来计算??
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {
// Fling enough to move left
snapToScreen(mCurScreen - 1);
--page;
pageListener.page(Math.abs(getCurScreen()));
Log.v("csh", "///////////////"+page);
} else if (velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1) {
// Fling enough to move right
snapToScreen(mCurScreen + 1);
++page;
pageListener.page(Math.abs(getCurScreen()));
Log.v("csh", "///////////////"+page);
} else {
snapToDestination();
pageListener.page(Math.abs(getCurScreen()));
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
mTouchState = TOUCH_STATE_REST;
break;
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
break;
}
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//滑动的过程中不能让事件对子View进行分发
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
return true;
}
final float x = ev.getX();
switch (action)
{
case MotionEvent.ACTION_MOVE:
//是否进行了滑动,设置滑动状态
final int xDiff = (int) Math.abs(mLastMotionX - x);
if (xDiff > mTouchSlop)
{
mTouchState = TOUCH_STATE_SCROLLING;
}
break;
case MotionEvent.ACTION_DOWN:
mLastMotionX = x;
mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mTouchState = TOUCH_STATE_REST;
break;
}
return mTouchState != TOUCH_STATE_REST;
}
public void setPageListener(PageListener pageListener) {
this.pageListener = pageListener;
}
public interface PageListener {
void page(int page);
}
**//点击切换下一页的方法**在点击事件调用即可
public void advanceMove(){
if(mCurScreen<你的页数){ 之前没注意,加上这个点击的时候就不会超过页数了。
mCurScreen ++ ;
//使用动画控制偏移过程 , 3s内到位
mScroller.startScroll((mCurScreen-1) * getWidth(), 0, getWidth(), 0,3000);
//其实点击按钮的时候,系统会自动重新绘制View,我们还是手动加上吧。
invalidate();
pageListener.page(Math.abs(getCurScreen()));
//使用scrollTo一步到位
//scrollTo(curScreen * MultiScreenActivity.screenWidth, 0);
}
}
public voidRollbackMove(){//回退前一页
if(mCurScreen!=mDefaultScreen){//不能超过初始页
mCurScreen -- ;
//使用动画控制偏移过程 , 3s内到位
mScroller.startScroll((mCurScreen-1) * getWidth(), 0, getWidth(), 0,3000);
//其实点击按钮的时候,系统会自动重新绘制View,我们还是手动加上吧。
invalidate();
pageListener.page(Math.abs(getCurScreen()));
//使用scrollTo一步到位
//scrollTo(curScreen * MultiScreenActivity.screenWidth, 0);
}
}
}