Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理

《Android 滑动侧边栏(Sliding Menu)实现分析》

《Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动》

《Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理》(本篇文章)

《Android 滑动侧边栏(Sliding Menu)第二种实现方式1》




一、 有图有真相

Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理_第1张图片


二、分析与伪码

1. 添加onIntercepteEvent, 只有当手指在右侧视图上并且移动超过一定距离,满足这连个条件拦截交由ViewGoup执行滚动

[java]  view plain copy print ?
  1. @Override  
  2. public boolean onInterceptTouchEvent(MotionEvent ev) {  
  3.       
  4.     final int actioin = ev.getAction();  
  5.     final int x = (int) ev.getX();  
  6.       
  7.     switch (actioin) {  
  8.     case MotionEvent.ACTION_DOWN:  
  9.         mInterceptMotionX = x;  
  10.         break;  
  11.   
  12.     case MotionEvent.ACTION_MOVE:  
  13.         final int deltaX = x - mInterceptMotionX;  
  14.         final int distance = Math.abs(deltaX);  
  15.         // 点击区域必须在右侧视图,因为仅右侧视图可移动  
  16.         // 横向移动超过一定距离,可以自己根据需求改动  
  17.         if ( canSliding(ev) && distance > mTouchSlop * 2) {  
  18.   
  19.             // 置为初始值  
  20.             mLastX = x;  
  21.             if (mScrollRunnable != null) {  
  22.                 mScrollRunnable.endScroll();  
  23.                 mScrollRunnable = null;  
  24.             }  
  25.               
  26.             // 拦截Touch Event 交由当前ViewGruop onTouchEvent处理  
  27.             return true;  
  28.         }  
  29.           
  30.         break;  
  31.           
  32.     case MotionEvent.ACTION_UP:  
  33.     case MotionEvent.ACTION_CANCEL:   
  34.         mInterceptMotionX = 0;  
  35.         break;  
  36.     }  
  37.       
  38.     return false;  
  39. }  

2. 上面用到的判断是否是右侧视图改变canSliding方法内部实现改变,使用ViewGroup.dispatchTouchEvent中判断方式。

[java]  view plain copy print ?
  1. /** 
  2.  * 当前手指点击位置是否在右侧视图区域内 
  3.  *  
  4.  * @param event 
  5.  * @return true 可以滚动 
  6.  */  
  7. private boolean canSliding(MotionEvent event) {  
  8.       
  9.     final int scrolledXInt = (int) (event.getX() + getScrollX());  
  10.     final int scrolledYInt = (int) (event.getY() + getScrollY());  
  11.       
  12.     Rect frame = new Rect();  
  13.     mRightView.getHitRect(frame);  
  14.     if (frame.contains(scrolledXInt, scrolledYInt)) {  
  15.         return true;  
  16.     }  
  17.       
  18.     return false;  
  19. }  


3. 改变onTochEvent,ACTION_DOWN的处理放到onInterceptTouchEvent中了,而且ViewGroup也不需要拦截DOWN事件,所以DOWN事件从onTochEvent删除。

[java]  view plain copy print ?
  1. @Override  
  2. public boolean onTouchEvent(MotionEvent event) {  
  3.       
  4.     final int x = (int) event.getX();  
  5.       
  6.     switch (event.getAction()) {  
  7.     case MotionEvent.ACTION_MOVE:  
  8.           
  9.         scrollIfNeed(x);  
  10.         return true;  
  11.           
  12.     case MotionEvent.ACTION_UP:  
  13.           
  14.         autoScrollIfNeed(x);  
  15.         break;  
  16.     }  
  17.       
  18.     return false;  
  19. }  

4. scrollIfNeed方法改变,右侧视图盖住左侧视图时,隐藏左侧视图,目的是为了此时左侧视图不接收Touch Event

[java]  view plain copy print ?
  1. private void scrollIfNeed(final int x) {  
  2.     // 计算与上次的偏移量  
  3.     int deltaX = x - mLastX;  
  4.       
  5.     // 减少移动次数  
  6.     if (x != mLastX) {  
  7.         // 显示  
  8.         if (mLeftView.getVisibility() != View.VISIBLE) {  
  9.             mLeftView.setVisibility(View.VISIBLE);  
  10.         }  
  11.           
  12.         int l = mRightView.getLeft();  
  13.         int t = mRightView.getTop();  
  14.         int b = mRightView.getBottom();  
  15.           
  16.         // 右侧视图的滑动区域,只能在左侧视图范围内滑动  
  17.         int rightViewLeft = Math.max(mLeftView.getLeft(), l + deltaX);  
  18.         rightViewLeft = Math.min(mLeftView.getRight(), rightViewLeft);  
  19.           
  20.         // 控制随手指滑动  
  21.         mRightView.layout(rightViewLeft, t, rightViewLeft + mRightView.getWidth(), b);  
  22.     }  
  23.       
  24.     // 滑动到最左侧  
  25.     if (mRightView.getLeft() == mLeftView.getLeft()) {  
  26.         mLeftView.setVisibility(View.INVISIBLE);  
  27.     }  
  28.       
  29.     // 记录当前值供下次计算         
  30.     mLastX = x;  
  31. }  


三、完整源码下载

源码下载地址



原文地址:http://blog.csdn.net/love_world_/article/details/8666210

你可能感兴趣的:(android)