当前位置: 代码迷 >> Iphone >> 应用luncher实现类似iphone平滑滑动效果
  详细解决方案

应用luncher实现类似iphone平滑滑动效果

热度:79   发布时间:2016-04-25 06:28:50.0
使用luncher实现类似iphone平滑滑动效果
import android.content.Context;   import android.util.Log;   import android.content.res.TypedArray;   import android.util.AttributeSet;   import android.view.MotionEvent;   import android.view.VelocityTracker;   import android.view.View;   import android.view.ViewGroup;   import android.view.ViewConfiguration;   import android.widget.Scroller;     public class DragableSpace extends ViewGroup {       private Scroller mScroller;       private VelocityTracker mVelocityTracker;         private int mScrollX = 0;       private int mCurrentScreen = 0;         private float mLastMotionX;         private static final String LOG_TAG = "DragableSpace";         private static final int SNAP_VELOCITY = 1000;         private final static int TOUCH_STATE_REST = 0;       private final static int TOUCH_STATE_SCROLLING = 1;         private int mTouchState = TOUCH_STATE_REST;         private int mTouchSlop = 0;         public DragableSpace(Context context) {           super(context);           mScroller = new Scroller(context);             mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();             this.setLayoutParams(new ViewGroup.LayoutParams(                       ViewGroup.LayoutParams.WRAP_CONTENT,                       ViewGroup.LayoutParams.FILL_PARENT));       }         public DragableSpace(Context context, AttributeSet attrs) {           super(context, attrs);           mScroller = new Scroller(context);             mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();             this.setLayoutParams(new ViewGroup.LayoutParams(                       ViewGroup.LayoutParams.WRAP_CONTENT ,                       ViewGroup.LayoutParams.FILL_PARENT));             TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.DragableSpace);           mCurrentScreen = a.getInteger(R.styleable.DragableSpace_default_screen, 0);       }         @Override      public boolean onInterceptTouchEvent(MotionEvent ev) {                                 final int action = ev.getAction();           if ((action == MotionEvent.ACTION_MOVE)                   && (mTouchState != TOUCH_STATE_REST)) {               return true;                   }             final float x = ev.getX();             switch (action) {               case MotionEvent.ACTION_MOVE:                                                         final int xDiff = (int) Math.abs(x - mLastMotionX);                     boolean xMoved = xDiff > mTouchSlop;                     if (xMoved) {                       // Scroll if the user moved far enough along the X axis                       mTouchState = TOUCH_STATE_SCROLLING;                   }                   break;                 case MotionEvent.ACTION_DOWN:                   // Remember location of down touch                   mLastMotionX = x;                                       mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;                   break;                 case MotionEvent.ACTION_CANCEL:               case MotionEvent.ACTION_UP:                   // Release the drag                   mTouchState = TOUCH_STATE_REST;                   break;           }                       return mTouchState != TOUCH_STATE_REST;       }         @Override      public boolean onTouchEvent(MotionEvent event) {             if (mVelocityTracker == null) {               mVelocityTracker = VelocityTracker.obtain();           }           mVelocityTracker.addMovement(event);             final int action = event.getAction();           final float x = event.getX();             switch (action) {               case MotionEvent.ACTION_DOWN:                   Log.i(LOG_TAG, "event : down");                                     if (!mScroller.isFinished()) {                       mScroller.abortAnimation();                   }                     // Remember where the motion event started                   mLastMotionX = x;                   break;               case MotionEvent.ACTION_MOVE:                   // Log.i(LOG_TAG,"event : move");                   // if (mTouchState == TOUCH_STATE_SCROLLING) {                   // Scroll to follow the motion event                   final int deltaX = (int) (mLastMotionX - x);                   mLastMotionX = x;                     //Log.i(LOG_TAG, "event : move, deltaX " + deltaX + ", mScrollX " + mScrollX);                     if (deltaX < 0) {                       if (mScrollX > 0) {                           scrollBy(Math.max(-mScrollX, deltaX), 0);                       }                   } else if (deltaX > 0) {                       final int availableToScroll = getChildAt(getChildCount() - 1)                           .getRight()                           - mScrollX - getWidth();                       if (availableToScroll > 0) {                           scrollBy(Math.min(availableToScroll, deltaX), 0);                       }                   }                   // }                   break;               case MotionEvent.ACTION_UP:                   Log.i(LOG_TAG, "event : up");                   // if (mTouchState == TOUCH_STATE_SCROLLING) {                   final VelocityTracker velocityTracker = mVelocityTracker;                   velocityTracker.computeCurrentVelocity(1000);                   int velocityX = (int) velocityTracker.getXVelocity();                     if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {                       // Fling hard enough to move left                       snapToScreen(mCurrentScreen - 1);                   } else if (velocityX < -SNAP_VELOCITY                           && mCurrentScreen < getChildCount() - 1) {                       // Fling hard enough to move right                       snapToScreen(mCurrentScreen + 1);                   } else {                       snapToDestination();                   }                     if (mVelocityTracker != null) {                       mVelocityTracker.recycle();                       mVelocityTracker = null;                   }                   // }                   mTouchState = TOUCH_STATE_REST;                   break;               case MotionEvent.ACTION_CANCEL:                   Log.i(LOG_TAG, "event : cancel");                   mTouchState = TOUCH_STATE_REST;           }           mScrollX = this.getScrollX();             return true;       }         private void snapToDestination() {           final int screenWidth = getWidth();           final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth;           Log.i(LOG_TAG, "from des");           snapToScreen(whichScreen);       }         public void snapToScreen(int whichScreen) {                    Log.i(LOG_TAG, "snap To Screen " + whichScreen);           mCurrentScreen = whichScreen;           final int newX = whichScreen * getWidth();           final int delta = newX - mScrollX;           mScroller.startScroll(mScrollX, 0, delta, 0, Math.abs(delta) * 2);                        invalidate();       }         public void setToScreen(int whichScreen) {           Log.i(LOG_TAG, "set To Screen " + whichScreen);           mCurrentScreen = whichScreen;           final int newX = whichScreen * getWidth();           mScroller.startScroll(newX, 0, 0, 0, 10);                        invalidate();       }         @Override      protected void onLayout(boolean changed, int l, int t, int r, int b) {           int childLeft = 0;             final int count = getChildCount();           for (int i = 0; i < count; i++) {               final View child = getChildAt(i);               if (child.getVisibility() != View.GONE) {                   final int childWidth = child.getMeasuredWidth();                   child.layout(childLeft, 0, childLeft + childWidth, child                           .getMeasuredHeight());                   childLeft += childWidth;               }           }         }         @Override      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {           super.onMeasure(widthMeasureSpec, heightMeasureSpec);             final int width = MeasureSpec.getSize(widthMeasureSpec);           final int widthMode = MeasureSpec.getMode(widthMeasureSpec);           if (widthMode != MeasureSpec.EXACTLY) {               throw new IllegalStateException("error mode.");           }             final int heightMode = MeasureSpec.getMode(heightMeasureSpec);           if (heightMode != MeasureSpec.EXACTLY) {               throw new IllegalStateException("error mode.");           }             // The children are given the same width and height as the workspace           final int count = getChildCount();           for (int i = 0; i < count; i++) {               getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);           }           Log.i(LOG_TAG, "moving to screen "+mCurrentScreen);           scrollTo(mCurrentScreen * width, 0);             }           @Override      public void computeScroll() {           if (mScroller.computeScrollOffset()) {               mScrollX = mScroller.getCurrX();               scrollTo(mScrollX, 0);               postInvalidate();           }       }   } 

<?xml version="1.0" encoding="utf-8"?>   <com.matthieu.launcher.DragableSpace xmlns:app="http://schemas.android.com/apk/res/com.matthieu.launcher"      xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/space"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  app:default_screen="1"  >   <include android:id="@+id/left"  layout="@layout/left_screen" />   <include android:id="@+id/center"  layout="@layout/initial_screen" />   <include android:id="@+id/right"  layout="@layout/right_screen" />   </com.matthieu.launcher.DragableSpace> 

values/attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="DragableSpace">   <attr name="default_screen" format="integer"/>  </declare-styleable> </resources>


http://blog.sina.com.cn/s/blog_4d142b550100s1th.html

另一篇:
提取Launcher中的WorkSapce,可以左右滑动切换屏幕页面的类
http://blog.csdn.net/Yao_GUET/archive/2011/05/04/6393962.aspx

Android中使用GridView分页显示系统所安装的应用,支持拖动与手势滑动
http://blog.csdn.net/Yao_GUET/archive/2011/05/05/6397197.aspx

多抽屉效果 (类似最早QQ使用的效果)
http://blog.csdn.net/feng88724/archive/2011/02/24/6206388.aspx
1 楼 liu2604592 2011-10-28  
太棒了!!!
  相关解决方案