Android开发ScrollView上下左右滑动事件冲突整理一(根据事件)

主要通过重写 onInterceptTouchEvent 事件来解决,代码如下:

 

Java代码  收藏代码
  1. package com.cm.android.pad.view.itemView;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.util.DisplayMetrics;  
  6. import android.util.Log;  
  7. import android.view.MotionEvent;  
  8. import android.view.VelocityTracker;  
  9. import android.view.ViewConfiguration;  
  10. import android.view.WindowManager;  
  11. import android.widget.ScrollView;  
  12. import android.widget.Scroller;  
  13.   
  14. public class MultiScroll extends ScrollView {  
  15.   
  16.     private static final int ANIMATION_SCREEN_SET_DURATION_MILLIS = 500;  
  17.     // What fraction (1/x) of the screen the user must swipe to indicate a page change  
  18.     private static final int FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE = 4;  
  19.     private static final int INVALID_SCREEN = -1;  
  20.     /* 
  21.      * Velocity of a swipe (in density-independent pixels per second) to force a swipe to the 
  22.      * next/previous screen. Adjusted into mDensityAdjustedSnapVelocity on init. 
  23.      */  
  24.     private static final int SNAP_VELOCITY_DIP_PER_SECOND = 600;  
  25.     // Argument to getVelocity for units to give pixels per second (1 = pixels per millisecond).  
  26.     private static final int VELOCITY_UNIT_PIXELS_PER_SECOND = 1000;  
  27.   
  28.     private static final int TOUCH_STATE_REST = 0;  
  29.     private static final int TOUCH_STATE_HORIZONTAL_SCROLLING = 1;  
  30.     private static final int TOUCH_STATE_VERTICAL_SCROLLING = -1;  
  31.     private int mCurrentScreen;  
  32.     private int mDensityAdjustedSnapVelocity;  
  33.     private boolean mFirstLayout = true;  
  34.     private float mLastMotionX;  
  35.     private float mLastMotionY;  
  36.     //private OnScreenSwitchListener mOnScreenSwitchListener;  
  37.     private int mMaximumVelocity;  
  38.     private int mNextScreen = INVALID_SCREEN;  
  39.     private Scroller mScroller;  
  40.     private int mTouchSlop;  
  41.     private int mTouchState = TOUCH_STATE_REST;  
  42.     private VelocityTracker mVelocityTracker;  
  43.     private int mLastSeenLayoutWidth = -1;  
  44.       
  45.     public MultiScroll(Context context) {  
  46.         super(context);  
  47.         init();  
  48.     }  
  49.   
  50.     public MultiScroll(Context context, AttributeSet attrs, int defStyle) {  
  51.         super(context, attrs, defStyle);  
  52.         init();  
  53.     }  
  54.   
  55.     public MultiScroll(Context context, AttributeSet attrs) {  
  56.         super(context, attrs);  
  57.         init();  
  58.     }  
  59.       
  60.     private void init() {  
  61.         mScroller = new Scroller(getContext());  
  62.   
  63.         // Calculate the density-dependent snap velocity in pixels  
  64.         DisplayMetrics displayMetrics = new DisplayMetrics();  
  65.         ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()  
  66.                 .getMetrics(displayMetrics);  
  67.         mDensityAdjustedSnapVelocity =  
  68.                 (int) (displayMetrics.density * SNAP_VELOCITY_DIP_PER_SECOND);  
  69.   
  70.         final ViewConfiguration configuration = ViewConfiguration.get(getContext());  
  71.         mTouchSlop = configuration.getScaledTouchSlop();  
  72.         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();  
  73.     }  
  74.       
  75.   
  76.     @Override  
  77.     public boolean onInterceptTouchEvent(final MotionEvent ev) {  
  78.         /* 
  79.          * By Yoni Samlan: Modified onInterceptTouchEvent based on standard ScrollView's 
  80.          * onIntercept. The logic is designed to support a nested vertically scrolling view inside 
  81.          * this one; once a scroll registers for X-wise scrolling, handle it in this view and don't 
  82.          * let the children, but once a scroll registers for y-wise scrolling, let the children 
  83.          * handle it exclusively. 
  84.          */  
  85.         final int action = ev.getAction();  
  86.         boolean intercept = false;  
  87.   
  88.         switch (action) {  
  89.             case MotionEvent.ACTION_MOVE:  
  90.                   
  91.                 /* 
  92.                  * If we're in a horizontal scroll event, take it (intercept further events). But if 
  93.                  * we're mid-vertical-scroll, don't even try; let the children deal with it. If we 
  94.                  * haven't found a scroll event yet, check for one. 
  95.                  */  
  96.                 if (mTouchState == TOUCH_STATE_HORIZONTAL_SCROLLING) {  
  97.                     // Let children handle the events for the duration of the scroll event.  
  98.                     intercept = false;  
  99.                 } else if (mTouchState == TOUCH_STATE_VERTICAL_SCROLLING) {  
  100.                        /* 
  101.                      * We've already started a horizontal scroll; set intercept to true so we can 
  102.                      * take the remainder of all touch events in onTouchEvent. 
  103.                      */  
  104.                     intercept = true;  
  105.                 } else { // We haven't picked up a scroll event yet; check for one.  
  106.   
  107.                     /* 
  108.                      * If we detected a horizontal scroll event, start stealing touch events (mark 
  109.                      * as scrolling). Otherwise, see if we had a vertical scroll event -- if so, let 
  110.                      * the children handle it and don't look to intercept again until the motion is 
  111.                      * done. 
  112.                      */  
  113.   
  114.                     final float x = ev.getX();  
  115.                     final int xDiff = (int) Math.abs(x - mLastMotionX);  
  116.                     boolean xMoved = xDiff > mTouchSlop;  
  117.                       
  118.                     final float y = ev.getY();  
  119.                     final int yDiff = (int) Math.abs(y - mLastMotionY);  
  120.                     boolean yMoved = yDiff > mTouchSlop;  
  121.   
  122.                       
  123.                     if (xMoved) {  
  124.                         // Scroll if the user moved far enough along the X axis  
  125.                         if(xDiff>=yDiff)  
  126.                         mTouchState = TOUCH_STATE_HORIZONTAL_SCROLLING;  
  127.                         mLastMotionX = x;  
  128.                     }  
  129.   
  130.     
  131.   
  132.                     if (yMoved) {  
  133.                         if(yDiff>xDiff)  
  134.                         mTouchState = TOUCH_STATE_VERTICAL_SCROLLING;  
  135.                         mLastMotionY = y;  
  136.                     }  
  137.                 }  
  138.   
  139.                 break;  
  140.             case MotionEvent.ACTION_CANCEL:  
  141.             case MotionEvent.ACTION_UP:  
  142.                 // Release the drag.  
  143.                 mTouchState = TOUCH_STATE_REST;  
  144.                 intercept = false;  
  145.                 break;  
  146.             case MotionEvent.ACTION_DOWN:  
  147.                 /* 
  148.                  * No motion yet, but register the coordinates so we can check for intercept at the 
  149.                  * next MOVE event. 
  150.                  */  
  151.                 //Log.i("ViewPager-->", "Action_Down");  
  152.                  mTouchState = TOUCH_STATE_REST;  
  153.                 mLastMotionY = ev.getY();  
  154.                 mLastMotionX = ev.getX();  
  155.                 break;  
  156.             default:  
  157.                 break;  
  158.             }  
  159.   
  160.         Log.i("MultiScroll-->", intercept+"");  
  161.         return intercept;  
  162.     }  
  163.       
  164. }  
posted @ 2015-11-25 13:41  dongweiq  阅读(974)  评论(0编辑  收藏  举报