Advertisement
Guest User

Untitled

a guest
Dec 28th, 2010
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.98 KB | None | 0 0
  1. package com.matthieu.launcher;
  2.  
  3. import android.content.Context;
  4. import android.os.Parcel;
  5. import android.os.Parcelable;
  6. import android.util.Log;
  7. import android.content.res.TypedArray;
  8. import android.util.AttributeSet;
  9. import android.view.MotionEvent;
  10. import android.view.VelocityTracker;
  11. import android.view.View;
  12. import android.view.ViewGroup;
  13. import android.view.ViewConfiguration;
  14. import android.widget.Scroller;
  15.  
  16. public class DragableSpace extends ViewGroup {
  17.     private Scroller mScroller;
  18.     private VelocityTracker mVelocityTracker;
  19.  
  20.     private int mScrollX = 0;
  21.     private int mCurrentScreen = 0;
  22.  
  23.     private float mLastMotionX;
  24.  
  25.     private static final String LOG_TAG = "DragableSpace";
  26.  
  27.     private static final int SNAP_VELOCITY = 1000;
  28.  
  29.     private final static int TOUCH_STATE_REST = 0;
  30.     private final static int TOUCH_STATE_SCROLLING = 1;
  31.  
  32.     private int mTouchState = TOUCH_STATE_REST;
  33.  
  34.     private int mTouchSlop = 0;
  35.  
  36.     public DragableSpace(Context context) {
  37.         super(context);
  38.         mScroller = new Scroller(context);
  39.  
  40.         mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
  41.  
  42.         this.setLayoutParams(new ViewGroup.LayoutParams(
  43.                     ViewGroup.LayoutParams.WRAP_CONTENT,
  44.                     ViewGroup.LayoutParams.FILL_PARENT));
  45.     }
  46.  
  47.     public DragableSpace(Context context, AttributeSet attrs) {
  48.         super(context, attrs);
  49.         mScroller = new Scroller(context);
  50.  
  51.         mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
  52.  
  53.         this.setLayoutParams(new ViewGroup.LayoutParams(
  54.                     ViewGroup.LayoutParams.WRAP_CONTENT ,
  55.                     ViewGroup.LayoutParams.FILL_PARENT));
  56.  
  57.         TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.DragableSpace);
  58.         mCurrentScreen = a.getInteger(R.styleable.DragableSpace_default_screen, 0);
  59.     }
  60.  
  61.     @Override
  62.     public boolean onInterceptTouchEvent(MotionEvent ev) {
  63.         /*
  64.          * This method JUST determines whether we want to intercept the motion.
  65.          * If we return true, onTouchEvent will be called and we do the actual
  66.          * scrolling there.
  67.          */
  68.  
  69.         /*
  70.          * Shortcut the most recurring case: the user is in the dragging state
  71.          * and he is moving his finger. We want to intercept this motion.
  72.          */
  73.         final int action = ev.getAction();
  74.         if ((action == MotionEvent.ACTION_MOVE)
  75.                 && (mTouchState != TOUCH_STATE_REST)) {
  76.             return true;
  77.                 }
  78.  
  79.         final float x = ev.getX();
  80.  
  81.         switch (action) {
  82.             case MotionEvent.ACTION_MOVE:
  83.                 /*
  84.                  * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
  85.                  * whether the user has moved far enough from his original down touch.
  86.                  */
  87.  
  88.                 /*
  89.                  * Locally do absolute value. mLastMotionX is set to the y value
  90.                  * of the down event.
  91.                  */
  92.                 final int xDiff = (int) Math.abs(x - mLastMotionX);
  93.  
  94.                 boolean xMoved = xDiff > mTouchSlop;
  95.  
  96.                 if (xMoved) {
  97.                     // Scroll if the user moved far enough along the X axis
  98.                     mTouchState = TOUCH_STATE_SCROLLING;
  99.                 }
  100.                 break;
  101.  
  102.             case MotionEvent.ACTION_DOWN:
  103.                 // Remember location of down touch
  104.                 mLastMotionX = x;
  105.  
  106.                 /*
  107.                  * If being flinged and user touches the screen, initiate drag;
  108.                  * otherwise don't.  mScroller.isFinished should be false when
  109.                  * being flinged.
  110.                  */
  111.                 mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
  112.                 break;
  113.  
  114.             case MotionEvent.ACTION_CANCEL:
  115.             case MotionEvent.ACTION_UP:
  116.                 // Release the drag
  117.                 mTouchState = TOUCH_STATE_REST;
  118.                 break;
  119.         }
  120.  
  121.         /*
  122.          * The only time we want to intercept motion events is if we are in the
  123.          * drag mode.
  124.          */
  125.         return mTouchState != TOUCH_STATE_REST;
  126.     }
  127.  
  128.     @Override
  129.     public boolean onTouchEvent(MotionEvent event) {
  130.  
  131.         if (mVelocityTracker == null) {
  132.             mVelocityTracker = VelocityTracker.obtain();
  133.         }
  134.         mVelocityTracker.addMovement(event);
  135.  
  136.         final int action = event.getAction();
  137.         final float x = event.getX();
  138.  
  139.         switch (action) {
  140.             case MotionEvent.ACTION_DOWN:
  141.                 Log.i(LOG_TAG, "event : down");
  142.                 /*
  143.                  * If being flinged and user touches, stop the fling. isFinished
  144.                  * will be false if being flinged.
  145.                  */
  146.                 if (!mScroller.isFinished()) {
  147.                     mScroller.abortAnimation();
  148.                 }
  149.  
  150.                 // Remember where the motion event started
  151.                 mLastMotionX = x;
  152.                 break;
  153.             case MotionEvent.ACTION_MOVE:
  154.                 // Log.i(LOG_TAG,"event : move");
  155.                 // if (mTouchState == TOUCH_STATE_SCROLLING) {
  156.                 // Scroll to follow the motion event
  157.                 final int deltaX = (int) (mLastMotionX - x);
  158.                 mLastMotionX = x;
  159.  
  160.                 //Log.i(LOG_TAG, "event : move, deltaX " + deltaX + ", mScrollX " + mScrollX);
  161.  
  162.                 if (deltaX < 0) {
  163.                     if (mScrollX > 0) {
  164.                         scrollBy(Math.max(-mScrollX, deltaX), 0);
  165.                     }
  166.                 } else if (deltaX > 0) {
  167.                     final int availableToScroll = getChildAt(getChildCount() - 1)
  168.                         .getRight()
  169.                         - mScrollX - getWidth();
  170.                     if (availableToScroll > 0) {
  171.                         scrollBy(Math.min(availableToScroll, deltaX), 0);
  172.                     }
  173.                 }
  174.                 // }
  175.                 break;
  176.             case MotionEvent.ACTION_UP:
  177.                 Log.i(LOG_TAG, "event : up");
  178.                 // if (mTouchState == TOUCH_STATE_SCROLLING) {
  179.                 final VelocityTracker velocityTracker = mVelocityTracker;
  180.                 velocityTracker.computeCurrentVelocity(1000);
  181.                 int velocityX = (int) velocityTracker.getXVelocity();
  182.  
  183.                 if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
  184.                     // Fling hard enough to move left
  185.                     snapToScreen(mCurrentScreen - 1);
  186.                 } else if (velocityX < -SNAP_VELOCITY
  187.                         && mCurrentScreen < getChildCount() - 1) {
  188.                     // Fling hard enough to move right
  189.                     snapToScreen(mCurrentScreen + 1);
  190.                 } else {
  191.                     snapToDestination();
  192.                 }
  193.  
  194.                 if (mVelocityTracker != null) {
  195.                     mVelocityTracker.recycle();
  196.                     mVelocityTracker = null;
  197.                 }
  198.                 // }
  199.                 mTouchState = TOUCH_STATE_REST;
  200.                 break;
  201.             case MotionEvent.ACTION_CANCEL:
  202.                 Log.i(LOG_TAG, "event : cancel");
  203.                 mTouchState = TOUCH_STATE_REST;
  204.         }
  205.         mScrollX = this.getScrollX();
  206.  
  207.         return true;
  208.     }
  209.  
  210.     private void snapToDestination() {
  211.         final int screenWidth = getWidth();
  212.         final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth;
  213.         Log.i(LOG_TAG, "from des");
  214.         snapToScreen(whichScreen);
  215.     }
  216.  
  217.     public void snapToScreen(int whichScreen) {        
  218.         Log.i(LOG_TAG, "snap To Screen " + whichScreen);
  219.         mCurrentScreen = whichScreen;
  220.         final int newX = whichScreen * getWidth();
  221.         final int delta = newX - mScrollX;
  222.         mScroller.startScroll(mScrollX, 0, delta, 0, Math.abs(delta) * 2);            
  223.         invalidate();
  224.     }
  225.  
  226.     public void setToScreen(int whichScreen) {
  227.         Log.i(LOG_TAG, "set To Screen " + whichScreen);
  228.         mCurrentScreen = whichScreen;
  229.         final int newX = whichScreen * getWidth();
  230.         mScroller.startScroll(newX, 0, 0, 0, 10);            
  231.         invalidate();
  232.     }
  233.  
  234.     @Override
  235.     protected void onLayout(boolean changed, int l, int t, int r, int b) {
  236.         int childLeft = 0;
  237.  
  238.         final int count = getChildCount();
  239.         for (int i = 0; i < count; i++) {
  240.             final View child = getChildAt(i);
  241.             if (child.getVisibility() != View.GONE) {
  242.                 final int childWidth = child.getMeasuredWidth();
  243.                 child.layout(childLeft, 0, childLeft + childWidth, child
  244.                         .getMeasuredHeight());
  245.                 childLeft += childWidth;
  246.             }
  247.         }
  248.  
  249.     }
  250.  
  251.     @Override
  252.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  253.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  254.  
  255.         final int width = MeasureSpec.getSize(widthMeasureSpec);
  256.         final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  257.         if (widthMode != MeasureSpec.EXACTLY) {
  258.             throw new IllegalStateException("error mode.");
  259.         }
  260.  
  261.         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  262.         if (heightMode != MeasureSpec.EXACTLY) {
  263.             throw new IllegalStateException("error mode.");
  264.         }
  265.  
  266.         // The children are given the same width and height as the workspace
  267.         final int count = getChildCount();
  268.         for (int i = 0; i < count; i++) {
  269.             getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
  270.         }
  271.         Log.i(LOG_TAG, "moving to screen "+mCurrentScreen);
  272.         scrollTo(mCurrentScreen * width, 0);      
  273.     }  
  274.  
  275.     @Override
  276.     public void computeScroll() {
  277.         if (mScroller.computeScrollOffset()) {
  278.             mScrollX = mScroller.getCurrX();
  279.             scrollTo(mScrollX, 0);
  280.             postInvalidate();
  281.         }
  282.     }
  283.    
  284.     /**
  285.      * Return the parceable instance to be saved
  286.      */
  287.     @Override
  288.     protected Parcelable onSaveInstanceState() {
  289.       final SavedState state = new SavedState(super.onSaveInstanceState());
  290.       state.currentScreen = mCurrentScreen;
  291.       return state;
  292.     }
  293.  
  294.  
  295.     /**
  296.      * Restore the previous saved current screen
  297.      */
  298.     @Override
  299.     protected void onRestoreInstanceState(Parcelable state) {
  300.       SavedState savedState = (SavedState) state;
  301.       super.onRestoreInstanceState(savedState.getSuperState());
  302.       if (savedState.currentScreen != -1) {
  303.         mCurrentScreen = savedState.currentScreen;
  304.       }
  305.     }
  306.  
  307.     // ========================= INNER CLASSES ==============================
  308.  
  309.     public interface onViewChangedEvent{      
  310.       void onViewChange (int currentViewIndex);
  311.     }
  312.  
  313.     /**
  314.      * A SavedState which save and load the current screen
  315.      */
  316.     public static class SavedState extends BaseSavedState {
  317.       int currentScreen = -1;
  318.  
  319.       /**
  320.        * Internal constructor
  321.        *
  322.        * @param superState
  323.        */
  324.       SavedState(Parcelable superState) {
  325.         super(superState);
  326.       }
  327.  
  328.       /**
  329.        * Private constructor
  330.        *
  331.        * @param in
  332.        */
  333.       private SavedState(Parcel in) {
  334.         super(in);
  335.         currentScreen = in.readInt();
  336.       }
  337.  
  338.       /**
  339.        * Save the current screen
  340.        */
  341.       @Override
  342.       public void writeToParcel(Parcel out, int flags) {
  343.         super.writeToParcel(out, flags);
  344.         out.writeInt(currentScreen);
  345.       }
  346.  
  347.       /**
  348.        * Return a Parcelable creator
  349.        */
  350.       public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
  351.         public SavedState createFromParcel(Parcel in) {
  352.           return new SavedState(in);
  353.         }
  354.  
  355.         public SavedState[] newArray(int size) {
  356.           return new SavedState[size];
  357.         }
  358.       };
  359.     }
  360.  
  361. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement