参考:http://blog.csdn.net/assassin4824/archive/2011/05/30/6454923.aspx
http://blog.sina.com.cn/s/blog_4d142b550100s1sx.html
http://blog.csdn.net/xiaoxiaobian3310903/archive/2011/05/24/6443250.aspx
http://www.ibm.com/developerworks/cn/opensource/os-cn-android-anmt2/
ScrollLayout.java
package com.lp;
import android.content.Context;
import android.graphics.Canvas;
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;
/** * 仿Launcher中的WorkSapce,可以左右滑动切换屏幕的类 */
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 = 600;
private int mTouchState = TOUCH_STATE_REST;
private int mTouchSlop;
private float mLastMotionX;
private float mLastMotionY;
public ScrollLayout(Context context, AttributeSet attrs)
{
this(context, attrs, 0); // TODO Auto-generated constructor stub
}
public ScrollLayout(Context context, AttributeSet attrs, int defStyle)
{ super(context, attrs, defStyle); // TODO Auto-generated constructor stub
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)
{ // TODO Auto-generated method stub
if (changed)
{
int childLeft = 0;
final int childCount = getChildCount();
for (int i=0; i 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; } return true; } //这个感觉没什么作用 不管true还是false 都是会执行onTouchEvent的 因为子view里面onTouchEvent返回false了 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub Log.e(TAG, "onInterceptTouchEvent-slop:"+mTouchSlop); 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: Log.e(TAG,"onInterceptTouchEvent move"); final int xDiff = (int)Math.abs(mLastMotionX-x); if (xDiff>mTouchSlop) { mTouchState = TOUCH_STATE_SCROLLING; } break; case MotionEvent.ACTION_DOWN: Log.e(TAG,"onInterceptTouchEvent down"); mLastMotionX = x; mLastMotionY = y; Log.e(TAG,mScroller.isFinished()+""); mTouchState = mScroller.isFinished()? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: Log.e(TAG,"onInterceptTouchEvent up or cancel"); mTouchState = TOUCH_STATE_REST; break; } Log.e(TAG,mTouchState+"===="+TOUCH_STATE_REST); return mTouchState != TOUCH_STATE_REST; } }
main.xml