我怎样才能使这个ScrollLayout循环?

时间:2014-04-17 23:50:38

标签: android loops

我找到了一些人的代码,一个scrollLayout,它的视图组可以保存一些视图,你可以在其中滑动视图,如android的视图寻呼机。例如,如果我有3个意见。 V0,V1,V2。当我刷过scrollLayout时,它调用了onViewChange(View v),v就是你所看到的视图。但现在我想循环查看其中的视图,我该怎么做呢?我的要求是, 当我继续滑动它时,结果是,v0,v1,v2 v0,v1,v2,v0,v1,v2 ......

1 个答案:

答案 0 :(得分:0)

public class ScrollLayout extends ViewGroup {
private static final String TAG = "ScrollLayout";
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private int mCurScreen;
private int mDefaultScreen = 0;
private static final int TOUCH_STATE_REST = 0;
private static final int TOUCH_STATE_SCROLLING = 1;
private static final int SNAP_VELOCITY = 9600;
private int mTouchState = TOUCH_STATE_REST;
private int mTouchSlop;
private float mLastMotionX;
private float mLastMotionY;
private OnViewChangeListener mOnViewChangeListener;

/**
 * 设置是否可左右滑动
 * @author liux
 */
private boolean isScroll = true;
public void setIsScroll(boolean b) {
    this.isScroll = b;
}

public ScrollLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mScroller = new Scroller(context);
    mCurScreen = mDefaultScreen;
    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;
        }
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //Log.e(TAG, "onMeasure");
    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!");
    }
    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);
    }
    // Log.e(TAG, "moving to screen "+mCurScreen);
    scrollTo(mCurScreen * width, 0);
}

/**
 * According to the position of current layout scroll to the destination
 * page.
 */
public void snapToDestination() {
    final int screenWidth = getWidth();
    final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
    snapToScreen(destScreen);
}

public void snapToScreen(int whichScreen) {
    //是否可滑动
    if(!isScroll) {
        this.setToScreen(whichScreen);
        return;
    }

    scrollToScreen(whichScreen);
}

public void scrollToScreen(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();
        mScroller.startScroll(getScrollX(), 0, delta, 0,
                Math.abs(delta) * 1);//持续滚动时间 以毫秒为单位
        mCurScreen = whichScreen;
        invalidate(); // Redraw the layout

        if (mOnViewChangeListener != null)
        {
            mOnViewChangeListener.OnViewChange(mCurScreen);
        }
    }
}

public void setToScreen(int whichScreen) {
    whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
    mCurScreen = whichScreen;
    scrollTo(whichScreen * getWidth(), 0);

    if (mOnViewChangeListener != null)
    {
        mOnViewChangeListener.OnViewChange(mCurScreen);
    }
}

public int getCurScreen() {
    return mCurScreen;
}

@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
        scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        postInvalidate();
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    //是否可滑动
    if(!isScroll) {
        return false;
    }

    Log.d("lightmanTouch", "Scroll onTouch "+event.getAction());



    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(event);
    final int action = event.getAction();
    final float x = event.getX();
    final float y = event.getY();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        //Log.e(TAG, "event down!");
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }
        mLastMotionX = x;

        //---------------New Code----------------------
        mLastMotionY = y;
        //---------------------------------------------

        break;
    case MotionEvent.ACTION_MOVE:
        int deltaX = (int) (mLastMotionX - x);

        //---------------New Code----------------------
        int deltaY = (int) (mLastMotionY - y);
        if(Math.abs(deltaX) < 200 && Math.abs(deltaY) > 50)
            break;
        mLastMotionY = y;
        //-------------------------------------

        mLastMotionX = x;
        if(Math.abs(deltaX) > 10)
        scrollBy(deltaX, 0);
        Log.d("movescroll", "deltax = "+ deltaX);
        break;
    case MotionEvent.ACTION_UP:
        //Log.e(TAG, "event : up");
        // if (mTouchState == TOUCH_STATE_SCROLLING) {
        final VelocityTracker velocityTracker = mVelocityTracker;
        velocityTracker.computeCurrentVelocity(1000);
        int velocityX = (int) velocityTracker.getXVelocity();
        //Log.e(TAG, "velocityX:" + velocityX);
        if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {
            // Fling enough to move left
            //Log.e(TAG, "snap left");
            snapToScreen(mCurScreen - 1);
        } else if (velocityX < -SNAP_VELOCITY
                && mCurScreen < getChildCount() - 1) {
            // Fling enough to move right
            //Log.e(TAG, "snap right");
            snapToScreen(mCurScreen + 1);
        } else {
            snapToDestination();
        }
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
        // }
        mTouchState = TOUCH_STATE_REST;
        break;
    case MotionEvent.ACTION_CANCEL:
        mTouchState = TOUCH_STATE_REST;
        break;
    }
    Log.d("SCROLLL", "before true    "+System.currentTimeMillis());
    return true;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    //Log.e(TAG, "onInterceptTouchEvent-slop:" + mTouchSlop);
    final int action = ev.getAction();
    if ((action == MotionEvent.ACTION_MOVE)
            && (mTouchState != TOUCH_STATE_REST)) {

        if(isScroll)
            return true;
        else
        return false;
    }
    final float x = ev.getX();
    final float y = ev.getY();
    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;
        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;
    }


    if(isScroll)
        return mTouchState != TOUCH_STATE_REST;
    else
        return false;
}

/**
 * 设置屏幕切换监听器
 * @param listener
 */
public void SetOnViewChangeListener(OnViewChangeListener listener)
{
    mOnViewChangeListener = listener;
}

/**
 * 屏幕切换监听器
 * @author liux
 */
public interface OnViewChangeListener {
    public void OnViewChange(int view);
}


@Override  
protected void dispatchDraw(Canvas canvas) {  
    super.dispatchDraw(canvas);  
    int scrollX = getScrollX();  
    final int N = getChildCount();  
    final int width = getWidth();  
    if (scrollX < 0) {  
        View lastChild = getChildAt(N - 1);  
        Log.d("TEST", "draw extra left ,scrollX is : " + scrollX + " width:"+lastChild.getWidth());  
        // end of first view and draw last view at its left  
        canvas.save();  
        canvas.translate(-width, 0);  
        canvas.clipRect(0, 0, width, getBottom());  
        lastChild.draw(canvas);  
        canvas.restore();  
    } else if (scrollX > (N - 1) * width) {  
        Log.d("TEST", "draw extra right ,scrollX is : " + scrollX);  
        View firstChild = getChildAt(0);  
        canvas.save();  
        canvas.translate(N * width, 0);  
        canvas.clipRect(0, 0, width, getBottom());  
        firstChild.draw(canvas);  
        canvas.restore();  
    }  
}   

}