Android实现滑动的七种方法

1.layout方法

每次移动后,调用layout()方法对自己重新布局从而达到移动的效果

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public boolean onTouchEvent(MotionEvent event) {  
  3.     int x = (int) event.getX();  
  4.     int y = (int) event.getY();  
  5.     switch (event.getAction()) {  
  6.         case MotionEvent.ACTION_DOWN:  
  7.             // 记录触摸点坐标  
  8.             lastX = x;  
  9.             lastY = y;  
  10.             break;  
  11.         case MotionEvent.ACTION_MOVE:  
  12.             // 计算偏移量  
  13.             int offsetX = x - lastX;  
  14.             int offsetY = y - lastY;  
  15.             // 在当前left、top、right、bottom的基础上加上偏移量  
  16.             layout(getLeft() + offsetX,  
  17.                     getTop() + offsetY,  
  18.                     getRight() + offsetX,  
  19.                     getBottom() + offsetY);  
  20.             break;  
  21.     }  
  22.     return true;  
  23. }  

 

 

2.offsetLeftAndRight()和offsetTopAndBottom()

系统提供的一个对左右、上下移动的API封装,效果和使用layout()一样

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. offsetLeftAndRight(offsetX);  
  2. offsetTopAndBottom(offsetY);  

 

 

3.LayoutParams

LayoutParams里保存了View的布局参数,通常通过改变LayoutParams来改变一个View的位置都是通过改变这个View的Margin属性。

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. case MotionEvent.ACTION_MOVE:  
  2.     // 计算偏移量  
  3.     int offsetX = x - lastX;  
  4.     int offsetY = y - lastY;  
  5.     ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();  
  6.     layoutParams.leftMargin = getLeft() + offsetX;  
  7.     layoutParams.topMargin = getTop() + offsetY;  
  8.     setLayoutParams(layoutParams);  
  9.     break;  

 

 

4.ScrollTo与ScrollBy

这两个方法移动的是View的内容,我们应该在要移动的View所在的ViewGroup中来使用这两个方法。

这两个方法的区别是scrollTo(x, y)表示移动到一个具体的坐标点(x, y),而scrollBy(dx, dy)表示移动的增量为dx、dy。

同时要想实现跟随手指一动而华东的效果,需要将偏移量设置为负数

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public boolean onTouchEvent(MotionEvent event) {  
  3.     int x = (int) event.getX();  
  4.     int y = (int) event.getY();  
  5.     switch (event.getAction()) {  
  6.         case MotionEvent.ACTION_DOWN:  
  7.             lastX = (int) event.getX();  
  8.             lastY = (int) event.getY();  
  9.             break;  
  10.         case MotionEvent.ACTION_MOVE:  
  11.             int offsetX = x - lastX;  
  12.             int offsetY = y - lastY;  
  13.             ((View) getParent()).scrollBy(-offsetX, -offsetY);  
  14.             break;  
  15.     }  
  16.     return true;  
  17. }  

 

 

5.Scroller类

通过Scroller类可以实现平滑移动的效果,而不再是瞬间完成的动作。

使用Scroller类需要三个步骤:

 

  • 初始化Scroller
  • 重写computeScroll()方法。用来判断是否完成了整个滑动
  • 开始滑动。startScroll(int startX, int startY, int dx, int dy, int duration)和startScroll(int startX, int startY, int dx, int dy)方法,区别是其中一个具有指定时长
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. private void ininView(Context context) {  
  2.     // 初始化Scroller  
  3.     mScroller = new Scroller(context);  
  4. }  
  5.   
  6. @Override  
  7. public void computeScroll() {  
  8.     super.computeScroll();  
  9.     // 判断Scroller是否执行完毕  
  10.     if (mScroller.computeScrollOffset()) {  
  11.         ((View) getParent()).scrollTo(  
  12.                 mScroller.getCurrX(),  
  13.                 mScroller.getCurrY());  
  14.         // 通过重绘来不断调用computeScroll  
  15.         invalidate();  
  16.     }  
  17. }  
  18.   
  19. @Override  
  20. public boolean onTouchEvent(MotionEvent event) {  
  21.     int x = (int) event.getX();  
  22.     int y = (int) event.getY();  
  23.     switch (event.getAction()) {  
  24.         case MotionEvent.ACTION_DOWN:  
  25.             lastX = (int) event.getX();  
  26.             lastY = (int) event.getY();  
  27.             break;  
  28.         case MotionEvent.ACTION_MOVE:  
  29.             int offsetX = x - lastX;  
  30.             int offsetY = y - lastY;  
  31.             ((View) getParent()).scrollBy(-offsetX, -offsetY);  
  32.             break;  
  33.         case MotionEvent.ACTION_UP:  
  34.             // 手指离开时,执行滑动过程  
  35.             View viewGroup = ((View) getParent());  
  36.             mScroller.startScroll(  
  37.                     viewGroup.getScrollX(),  
  38.                     viewGroup.getScrollY(),  
  39.                     -viewGroup.getScrollX(),  
  40.                     -viewGroup.getScrollY());  
  41.             invalidate();  
  42.             break;  
  43.     }  
  44.     return true;  
  45. }  
 

6.属性动画

详情见属性动画的介绍
 

7.ViewDragHelper

使用步骤:
  • 初始化ViewDragHelper
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. mViewDragHelper = ViewDragHelper.create(this, callback);  

  • 拦截事件
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public boolean onInterceptTouchEvent(MotionEvent ev) {  
  3.     return mViewDragHelper.shouldInterceptTouchEvent(ev);  
  4. }  
  5.   
  6. @Override  
  7. public boolean onTouchEvent(MotionEvent event) {  
  8.     //将触摸事件传递给ViewDragHelper,此操作必不可少  
  9.     mViewDragHelper.processTouchEvent(event);  
  10.     return true;  
  11. }  
 
  • 处理computeScroll()
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public void computeScroll() {  
  3.     if (mViewDragHelper.continueSettling(true)) {  
  4.         ViewCompat.postInvalidateOnAnimation(this);  
  5.     }  
  6. }  
 
  • 处理回调CallBack
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. private ViewDragHelper.Callback callback =  
  2.         new ViewDragHelper.Callback() {  
  3.   
  4.             // 何时开始检测触摸事件  
  5.             @Override  
  6.             public boolean tryCaptureView(View child, int pointerId) {  
  7.                 //如果当前触摸的child是mMainView时开始检测  
  8.                 return mMainView == child;  
  9.             }  
  10.   
  11.             // 触摸到View后回调  
  12.             @Override  
  13.             public void onViewCaptured(View capturedChild,  
  14.                                        int activePointerId) {  
  15.                 super.onViewCaptured(capturedChild, activePointerId);  
  16.             }  
  17.   
  18.             // 当拖拽状态改变,比如idle,dragging  
  19.             @Override  
  20.             public void onViewDragStateChanged(int state) {  
  21.                 super.onViewDragStateChanged(state);  
  22.             }  
  23.   
  24.             // 当位置改变的时候调用,常用与滑动时更改scale等  
  25.             @Override  
  26.             public void onViewPositionChanged(View changedView,  
  27.                                               int left, int top, int dx, int dy) {  
  28.                 super.onViewPositionChanged(changedView, left, top, dx, dy);  
  29.             }  
  30.   
  31.             // 处理垂直滑动  
  32.             @Override  
  33.             public int clampViewPositionVertical(View child, int top, int dy) {  
  34.                 return 0;  
  35.             }  
  36.   
  37.             // 处理水平滑动  
  38.             @Override  
  39.             public int clampViewPositionHorizontal(View child, int left, int dx) {  
  40.                 return left;  
  41.             }  
  42.   
  43.             // 拖动结束后调用  
  44.             @Override  
  45.             public void onViewReleased(View releasedChild, float xvel, float yvel) {  
  46.                 super.onViewReleased(releasedChild, xvel, yvel);  
  47.                 //手指抬起后缓慢移动到指定位置  
  48.                 if (mMainView.getLeft() < 500) {  
  49.                     //关闭菜单  
  50.                     //相当于Scroller的startScroll方法  
  51.                     mViewDragHelper.smoothSlideViewTo(mMainView, 0, 0);  
  52.                     ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);  
  53.                 } else {  
  54.                     //打开菜单  
  55.                     mViewDragHelper.smoothSlideViewTo(mMainView, 300, 0);  
  56.                     ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);  
  57.                 }  
  58.             }  
  59.         };  

 

详细代码可见Android群英传

                      -------------------------------Android群英传第五章

posted @ 2016-11-28 14:29  天涯海角路  阅读(176)  评论(0)    收藏  举报