import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.Scroller; public class MultiViewGroup1 extends ViewGroup { private Context mContext; private static String TAG = "MultiViewGroup"; public int curScreen = 0; public void PageChage(int index) { } /* * 获取当前界面 */ public int getCurScreen() { return curScreen; } /* * 设置当前界面 */ public void setCurScreen(int curScreen) { //this.curScreen = curScreen; snapToScreen(curScreen); } private Scroller mScroller = null; private static final int TOUCH_STATE_REST = 0; private static final int TOUCH_STATE_SCROLLING = 1; private int mTouchState = TOUCH_STATE_REST; public static int SNAP_VELOCITY = 600; private int mTouchSlop = 0; private float mLastionMotionX = 0; private float mLastMotionY = 0; private VelocityTracker mVelocityTracker = null; public MultiViewGroup1(Context context) { super(context); mContext = context; init(); } public MultiViewGroup1(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); } private void init() { mScroller = new Scroller(mContext); mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); } public void moveToLeftSide() { if (curScreen >= getChildCount() - 1) { return; } curScreen++; mScroller.startScroll((curScreen - 1) * getWidth(), 0, getWidth(), 0, 3000); scrollTo(curScreen * getWidth(), 0); invalidate(); PageChage(curScreen); } public void moveToRightSide() { if (curScreen <= 0) { return; } curScreen--; mScroller.startScroll((curScreen + 1) * getWidth(), 0, -getWidth(), 0, 3000); scrollTo(curScreen * getWidth(), 0); invalidate(); PageChage(curScreen); } public void stopMove() { if (mScroller != null) { if (!mScroller.isFinished()) { int scrollCurX = mScroller.getCurrX(); // calculate destination screen int descScreen = (scrollCurX + getWidth() / 2) / getWidth(); mScroller.abortAnimation(); scrollTo(descScreen * getWidth(), 0); mScroller.forceFinished(true); curScreen = descScreen; } } } @Override public void computeScroll() { // TODO Auto-generated method stub if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub final int action = ev.getAction(); if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) { return true; } final float x = ev.getX(); final float y = ev.getY(); switch (action) { case MotionEvent.ACTION_MOVE: final int xDiff = (int) Math.abs(mLastionMotionX - x); if (xDiff > mTouchSlop) { mTouchState = TOUCH_STATE_SCROLLING; } break; case MotionEvent.ACTION_DOWN: mLastionMotionX = x; mLastMotionY = y; 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 boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); super.onTouchEvent(event); float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (mScroller != null) { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } } mLastionMotionX = x; break; case MotionEvent.ACTION_MOVE: int deltaX = (int) (mLastionMotionX - x); int deltaY = (int) (mLastMotionY - y); if (Math.abs(deltaX) < Math.abs(deltaY)) { break; } scrollBy(deltaX, 0); mLastionMotionX = x; break; case MotionEvent.ACTION_UP: final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000); int velocityX = (int) velocityTracker.getXVelocity(); if (velocityX > SNAP_VELOCITY && curScreen > 0) { // Fling enough to move left snapToScreen(curScreen - 1); } else if (velocityX < -SNAP_VELOCITY && curScreen < (getChildCount() - 1)) { snapToScreen(curScreen + 1); } else { snapToDestination(); } if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } mTouchState = TOUCH_STATE_REST; break; case MotionEvent.ACTION_CANCEL: mTouchState = TOUCH_STATE_REST; break; } return true; } private void snapToDestination() { int scrollX = getScrollX(); int scrollY = getScrollY(); int destScreen = (getScrollX() + getWidth() / 2) / getWidth(); snapToScreen(destScreen); } // 滑动到相应的View private void snapToScreen(int whichScreen) { //Log.i(TAG, curScreen+" "+whichScreen+" "+flag); if (whichScreen > getChildCount() - 1) whichScreen = getChildCount() - 1; boolean flag = curScreen != whichScreen; curScreen = whichScreen; int dx = curScreen * getWidth() - getScrollX(); mScroller.startScroll(getScrollX(), 0, dx, 0, Math.abs(dx) * 2); invalidate(); //如果界面变化,就执行 if (flag) { PageChage(curScreen); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); child.measure(getWidth(), height); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub int startLeft = 0; int startTop = 0; int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (child.getVisibility() != View.GONE) child.layout(startLeft, startTop, startLeft + getWidth(), startTop + getHeight()); startLeft = startLeft + getWidth(); } } }