android上下スムーズページめくり

11521 ワード

最近生存の圧力に迫られて、アルバイトをしなければなりません.だからブログにクリックを求めるリンクを追加しました.時間のあるブロガーの皆さん、クリックしてください.時間がないから無理しなくてもいいよ.しかし、安心してください.私は技術をしています.きっとリンクにウイルスがありません.私がアルバイトをしている淘宝店です.にこにこ.http://shop108130013.taobao.com.ありがとうございます.これからは毎週良いオリジナル技術の文章を書いてお返しします.
今日は仕事が忙しいので、ソースを貼ってから詳しく説明しましょう.
完全に実行できる上下ページのソースコードは、リソースページにアップロードされます.http://download.csdn.net/detail/fener10289/6284691
ページを上下にスライドさせるためのカスタムコントロールコードを主に実装します.
package com.example.flingpage; 
  
  
import android.content.Context; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.VelocityTracker; 
import android.view.View; 
import android.view.ViewConfiguration; 
import android.view.ViewGroup; 
import android.view.View.MeasureSpec; 
import android.widget.Scroller; 
  
/** 
*      ScrollView          
*/
public class DefinedScrollView extends ViewGroup { 
	//                ,         ,     ComputeScroll   
	private Scroller mScroller; 
	//          ,     GestureDetector 
	private VelocityTracker mVelocityTracker; 
	  
	//         
	private int mCurrentScreen; 
	//       
	//private int mPage = 0; 
	//         
	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 = 600; 
	//             
	private int mTouchState = TOUCH_STATE_REST; 
	  
	//      
	private int mTouchSlop; 
/*	//           
	private float mLastMotionX; */
	//           
	private float mLastMotionY; 
	  
	private PageListener pageListener; 
  
	/** 
	*               
	*  
	* @param context 
	* @param attrs 
	* @param defStyle 
	* ScrollView      
	*/
	public DefinedScrollView(Context context, AttributeSet attrs, int defStyle) { 
		super(context, attrs, defStyle); 
		mScroller = new Scroller(context); 
		//            ,      
		mCurrentScreen = mDefaultScreen; 
		//      ,       ,                   
		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); 
	} 
  
	public DefinedScrollView(Context context, AttributeSet attrs) { 
	// 0       
		this(context, attrs, 0); 
	} 
  
	/** 
	*         view,      view        ,   getChildCount()-1      view。 
	*/
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) { 
		///int childLeft = 0; 
		int childTop = 0;
		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(); 
				final int childHeight = childView.getMeasuredHeight();
/*				childView.layout(childLeft, 0, childLeft + childWidth, 
				childView.getMeasuredHeight()); */
				childView.layout(0, childTop, childView.getMeasuredHeight(), 
						childTop + childHeight); 
				childTop +=childHeight;
				///childLeft += childWidth; 
			} 
		} 
	}  
  
	/** 
	* onMeasure                     .       ,“         ?”,        ——widthMeasureSpec heightMeasureSpec. 
	*     setMeasuredDimension  ,                  。 
	*  
	*setMeasuredDimension(measuredHeight, measuredWidth); 
	  
	*  
	*      width height fill_parent ,         view measure        EXACTLY,   view          ,         。 
	*      wrap_content ,       AT_MOST,    view        ,   view               。 
	*   view          ,      EXACTLY,  MeasureSpec UNSPECIFIED                 。  
	*/
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
		super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
		/////final int width = MeasureSpec.getSize(widthMeasureSpec); 
		final int height = MeasureSpec.getSize(heightMeasureSpec); 
		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); 
		} 
		//          (x , y)   ,   (  )    (x , y)   。 
		// View Content      (x,y), View           。  Content   View   ,          。 
		////scrollTo(mCurrentScreen * width, 0); 
		scrollTo(0,mCurrentScreen*height); 
	} 
  
	/** 
	* According to the position of current layout scroll to the destination 
	* page. 
	*                     
	*/
	public void snapToDestination() { 
		////final int screenWidth = getWidth(); 
		final int screenHeight = getHeight();
		////final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth; 
		final int destScreen = (getScrollY() + screenHeight / 2) / screenHeight; 
		//    x              
		snapToScreen(destScreen); 
	} 
  
	/** 
	*        ,   
	*                 
	* @param whichScreen 
	*/
	public void snapToScreen(int whichScreen) { 
		// get the valid layout page 
		whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); 
		///if (getScrollX() != (whichScreen * getWidth())) { 
		if (getScrollY() != (whichScreen * getHeight())) { 	  
			final int delta = whichScreen * getHeight() - getScrollY(); 
			///mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2); 
			mScroller.startScroll(0,getScrollY(), 0,delta,  Math.abs(delta) * 2); 
			mCurrentScreen = whichScreen; 
			if(mCurrentScreen>Configure.curentPage){ 
				Configure.curentPage = whichScreen; 
				pageListener.page(Configure.curentPage); 
			}else if(mCurrentScreen<Configure.curentPage){ 
				Configure.curentPage = whichScreen; 
				pageListener.page(Configure.curentPage); 
			} 
			invalidate(); // Redraw the layout 
		} 
	} 
  
	/** 
	*        
	*/
	public int getCurScreen() { 
		return mCurrentScreen; 
	} 
	  
	/** 
	*           
	*/ 
	public int getPage() { 
		return Configure.curentPage; 
	} 
	  
	  
	public void setToScreen(int whichScreen) { 
		whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); 
		mCurrentScreen = whichScreen; 
		///scrollTo(whichScreen * getWidth(), 0); 
		scrollTo(0,whichScreen * getHeight() ); 
	} 
  
	/** 
	*              、    、        (setCurrentScreen(mCurrentScreen);)。 
	*  
	*  
	*                          mScrollX mScrollY  。 
	*                 Scroller            。 
	*  ,         ,             Scroller    。 
	*/ 
	@Override
	public void computeScroll() { 
		//           ,        true           ,                         。 
		/** 
		*         (mScroller.computeScrollOffset() == true)     scrollTo   mScrollX、mScrollY            , 
		  
		  postInvalidate()        , 
		  
		postInvalidate()     invalidate()  , 
		  
		invalidate()      computeScroll  , 
		  
		            ,  mScroller.computeScrollOffset()   false            
		*/
		if (mScroller.computeScrollOffset()) { 
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 
			postInvalidate(); 
		} 
	} 
  
	/** 
	*             
	* @event   event               ,             ,       、             。                 。 
	* <A href='\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"' target='\"_blank\"'>@return</A>                    ,                                true,    false 
	*      :       ,             ,  MotionEvent.getAction()   MotionEvent.ACTION_DOWN,                    ,         ,               。  
	*      :              ,       onTouchEvent     ,            。 MotionEvent.getAction()   MotionEvent.ACTION_UP ,           。 
	*       :                    ,     MotionEvent.getAction()           MotionEvent.ACTION_MOVE     。 
	*/
	@Override
	public boolean onTouchEvent(MotionEvent event) { 
	  
		if (mVelocityTracker == null) { 
		//        (flinging         )   。 obtain()          
		mVelocityTracker = VelocityTracker.obtain(); 
		} 
		// addMovement(MotionEvent)   motion event   VelocityTracker     
		mVelocityTracker.addMovement(event); 
		  
		final int action = event.getAction(); 
		////final float x = event.getX(); 
		final float y = event.getY(); 
	  
		switch (action) { 
			case MotionEvent.ACTION_DOWN: 
				if (!mScroller.isFinished()) { 
					mScroller.abortAnimation(); 
				} 
				///mLastMotionX = x; 
				mLastMotionY = y; 
			break; 
			case MotionEvent.ACTION_MOVE: 
				///int deltaX = (int) (mLastMotionX - x); 
				///mLastMotionX = x; 
				int deltaY = (int) (mLastMotionY - y); 
				mLastMotionY = y; 
				//           (x , y)   ,  (  )       (x,y)    
				///scrollBy(deltaX, 0); 
				scrollBy(0, deltaY); 
			break; 
			case MotionEvent.ACTION_UP: 
				final VelocityTracker velocityTracker = mVelocityTracker; 
					//        ,  computeCurrentVelocity(int)        ,           , 
					//    getXVelocity()  getXVelocity()          。  
					//1000:        .1    ,               , 1000                。  
					velocityTracker.computeCurrentVelocity(1000); 
					///int velocityX = (int) velocityTracker.getXVelocity(); 
					int velocityY = (int) velocityTracker.getYVelocity();
					//        >600        ,                , 0 
					///if (velocityX > SNAP_VELOCITY && getCurScreen() > 0) { 
					if (velocityY > SNAP_VELOCITY && getCurScreen() > 0) { 
					// Fling enough to move left 
					snapToScreen(getCurScreen() - 1); 
					//--Configure.curentPage; 
					pageListener.page(Configure.curentPage); 
				} ///else if (velocityX < -SNAP_VELOCITY && getCurScreen() < getChildCount() - 1) { 
				else if (velocityY < -SNAP_VELOCITY && getCurScreen() < getChildCount() - 1) { 
					// Fling enough to move right 
					snapToScreen(getCurScreen() + 1); 
					//++Configure.curentPage; 
					//pageListener.page(Configure.curentPage); 
				} 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; 
	} 
	  
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) { 
		if(Configure.isMove) return false;//         
		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(mLastMotionX - x); 
			final int yDiff = (int) Math.abs(mLastMotionY - y); 
			////if (xDiff > mTouchSlop) { 
			if (yDiff > 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; 
		} 
		return mTouchState != TOUCH_STATE_REST; 
	} 
	  
	public void setPageListener(PageListener pageListener) { 
		this.pageListener = pageListener; 
	} 
	  
	public interface PageListener { 
		void page(int page); 
	} 
}