2014-04-17 5 views
0

일부 사람의 코드를 볼 수 있습니다.보기 그룹이 일부보기를 보유 할 수있는 scrollLayout이 있으며, 안드로이드의보기 호출기와 같이보기를 스 와이프 할 수 있습니다. 예를 들어,보기가 3 개인 경우. v0, v1, v2. scrollLayout을 스 와이프했을 때, onViewChange (View v)가 호출되었고, v는 사용자가 보는 것입니다.하지만 지금은 뷰를 반복하고 싶습니다. 어떻게 할 수 있습니까? 내가 슬쩍에게 그것을 계속 때 내 수요가 ... 결과는, V0, V1, V2의 V0, V1, V2, V0, V1, V2입니다 어떻게이 ScrollLayout 루프를 만들 수 있습니까?

답변

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(); 
    } 
} 

}

입니다
관련 문제