概述

Android中的滑动事件,实际上就是View的移动,原理和动画相似.本质就是不断的改变View的位置,.View的滑动我们需要了解一个类MotionEvent.

MotionEvent中封装了一些与触摸相关的东西,比如触摸事件Action,触摸坐标等,在一般View 的触摸事件中都包含这样一个参数.

既然是View的位置移动,那么在移动的过程中,我们都有哪些方法来改变一个View 的位置呢,

onTouchEvent

在View 类中,我们知道有一个layout方法是给View定位的 ,结合onTouchEvent方法 ,我们可以很好的实现一个View的移动.

int lastX, lastY;    @Override    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                lastX = rawX;                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                 layout(getLeft()+offsetX,                 getTop()+offsetY,                 getRight()+offsetX,                 getBottom()+offsetY);                lastX = rawX;                lastY = rawY;                break;        }        return true;    }

这里面使用了绝对坐标,使用绝对坐标的时候,需要在每次ACTION_MOVE后重新设置出事坐标.

offsetLeftAndRight()

使用offsetLeftAndRight();offsetTopAndBottom();方法,通过设置偏移量来滑动View

    int lastX, lastY;    @Override    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                lastX = rawX;                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                //layout(getLeft()+offsetX,                // getTop()+offsetY,                // getRight()+offsetX,                // getBottom()+offsetY);                offsetLeftAndRight(offsetX);                offsetTopAndBottom(offsetY);                lastX = rawX;                lastY = rawY;                break;        }        return true;    }

LayoutParams

LayoutParams,使用LayoutParams滑动View,通过改变布局参数来达到滑动View的目的.

 int lastX, lastY;    @Override    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                lastX = rawX;                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                // layout(getLeft()+offsetX,                // getTop()+offsetY,                // getRight()+offsetX,                // getBottom()+offsetY);// offsetLeftAndRight(offsetX);// offsetTopAndBottom(offsetY);                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();                layoutParams.leftMargin = getLeft() + offsetX ;                layoutParams.topMargin = getTop() +offsetY;                setLayoutParams(layoutParams);                lastX = rawX;                lastY = rawY;                break;        }        return true;    }

ScrollTo() ScrollBy()

使用ScrollTo() 和ScrollBy() 方法来改变View 的位置.

    int lastX, lastY;    @Override    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                lastX = rawX;                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                // layout(getLeft()+offsetX,                // getTop()+offsetY,                // getRight()+offsetX,                // getBottom()+offsetY);// offsetLeftAndRight(offsetX);// offsetTopAndBottom(offsetY);// ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();// layoutParams.leftMargin = getLeft() + offsetX ;// layoutParams.topMargin = getTop() +offsetY;// setLayoutParams(layoutParams);                ((View) getParent()).scrollBy( -offsetX, -offsetY);                lastX = rawX;                lastY = rawY;                break;        }        return true;    }

这里需要注意的是
1.首先我们的ScrollTo() and ScrollBy()方法移动的是View的Content
2.我们移动的是画布,因此需要设置相反的值,才能让View 跟随手指移动.

Scroller

使用Scroller类来移动View,与ScrollBy()方法关系紧密,ScrollBy()移动是瞬时完成,Scroller类在ACTION_MOVE中对偏移量进行划分,达到平滑效果.我们需要三个步骤

 mScroller = new Scroller(context);
@Override    public void computeScroll() {        super.computeScroll();        if (mScroller.computeScrollOffset()) {            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());            invalidate();        }    }
 case MotionEvent.ACTION_UP:                ViewGroup viewGroup = (ViewGroup) getParent();         mScroller.startScroll(viewGroup.getScrollX(),viewGroup.getScrollY(),-viewGroup.getScrollX(),-viewGroup.getScrollY());                invalidate();                break;

Property Animation

Android 属性动画,

        int w = text.getWidth();        int screenW = UiUtil.getScreenWidth();        int transX = screenW - w;        ObjectAnimator transAnim = ObjectAnimator.ofFloat(text, "translationX", 0, transX);

ViewDragHelper

使用v4包中的ViewDragHelper能很好的实现View的滑动和事件分发,典型谷歌官方的 Drawerlayout

ViewDragHelper实现QQ侧滑效果DragLayout[github]

更多相关文章

  1. 编译 Android(安卓)版本的 Opus 音频编解码库的方法
  2. Android(安卓)坐标系与视图坐标系图解
  3. android中进程与线程
  4. Android(安卓)下拉刷新框架实现、仿新浪微博、QQ好友动态滑到底
  5. Service与Android系统设计(2)-- Parcel
  6. 状态栏框架-- 深入Android应用开发:核心技术解析与最佳实践
  7. 关于Handler技术
  8. Android状态保存与恢复
  9. Android学习笔记之ImageSwitcher

随机推荐

  1. 大数据和云计算技术周报(第104期)
  2. 《数据科学家》2016年11月,让大数据更简单
  3. 大数据和云计算技术周报(第102期)
  4. 电商数据分析:用七句话学会用数据监控类目
  5. 给非科班出身的你,推荐几本统计学图书
  6. 批量制作:疫情防控小区出入证
  7. 18个高效WPS表格技巧,值得收藏
  8. Linux中shell脚本使用
  9. 你真知道如何高效用mapPartitions吗?
  10. spark streaming窗口及聚合操作后如何管