【Touch】触摸事件onTouch

触摸事件

1) onTouchListener

@Override
public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
      switch (action) {
        case MotionEvent.ACTION_DOWN: //手指按下
            break;
        case MotionEvent.ACTION_MOVE: //手指移动(从手指按下到抬起 move多次执行)
            break;
        case MotionEvent.ACTION_UP: //手指抬起
            break;
    }
    return true; //表示消费了触摸事件,onTouch之后才执行onClick,这里被消费了,所以,相关的点击事件不会执行。
}

使用event.getX();event.getY();来获取位置(手指按下,移动或者是抬起时的位置)。通过位置来判断手指滑动的方向。
.
【Touch】触摸事件onTouch_第1张图片
.
【Touch】触摸事件onTouch_第2张图片

简记:down>move 为左上

2) 触摸的边界问题(左右滑动为例)

【Touch】触摸事件onTouch_第3张图片

在左右滑动的过程中,需要对控件进行位置更改的,每一次更改位置,都需要保证将要移动到的位置需要在上面的x变化中,大于或者小于两边的边界值时,就取边界值。

3) onTouch 和onClick

onClick 的过程是手指按下和抬起的过程(中间,手指抖动会产生移动),可以将onClick看做是一种特殊的onTouch。如果onTouch 没有消费掉触摸事件(没有return true),在onTouch后, 紧接着会执行onClick事件;如果onTouch消费掉了触摸事件(return true),后面将不会再执行onClick事件。
需求较为复杂时,不仅需要touch事件也需要点击,甚至是长按事件,可以在onTouch中判断要进行哪一种事件(根据触摸的时间,距离等来判断)。

4) 滑动事件和VelocityTracker 速度跟踪

关于速度,速度是有方向的,往哪边运动。向左(上)滑动所产生的速度是负数,向右(下)滑动所产生的速度是正数。

VelocityTracker 跟踪手指滑动的速度, 怎么跟踪?

VelocityTracker velocityTracker = VelocityTracker.obtain();//获取跟踪类的实例

VelocityTracker(MotionEvent event);
然后就可以通过

velocity.getVelocityX();//获取x轴方向的速度
velocityTracker.getVelocityY();//获取y轴方向的速度

什么时候需要速度跟踪?
根据用户手指操作的速度来进行某些操作时,需要进行速度跟踪。例如,对slidMenu的操作,手指可能并没有滑动到显示menu的一半(往显示menu的方向进行滑动),但是,如果我滑动的速度很快,那么此时还是应该显示menu界面。


代码练习:
基于
郭霖–
Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
http://blog.csdn.net/guolin_blog/article/details/8714621

侧滑的简单实现思路:
界面本身是一个水平的LinearLayout布局文件,有menu+content两个(LinearLayout)控件,通过设置LL的margin来设置menu不可见。然后,通过手指的左右滑动,设置margin左右变化来显示内容,使用Velocity记录滑动过程的速度,当手指停止滑动时,根据手指抬起来的位置以及速度来判断menu是否完全显示,还是完全隐藏。

个人编码实现 onTouch部分:

@Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        velocityTracker.addMovement(event);//将当前事件添加到速度跟踪类 进行速度的跟踪

        //主要设置 手指的左右滑动
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mFirstDownX = event.getX();
                mDownX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                float mMoveX = event.getX();
                float dx = Math.abs(mDownX - mMoveX);
                //1、根据move的位置,判断用户手指是往哪边滑动的
                float mMarginX = mMenuParams.leftMargin;

                if (mMoveX < mDownX) {//向左滑
                    //左滑的条件是否满足
                    if (mMarginX <= 0 && mMarginX > -mMenuWidth) {
                        mMarginX = mMarginX - dx;
                    }
                } else {//向右滑
                    if (mMarginX < 0 && mMarginX >= -mMenuWidth) {
                        mMarginX = mMarginX + dx;
                    }
                }
                //保证 menu 的leftMargin 在-mMenuWidth-->0 这个范围之间
                mMarginX = mMarginX >= 0 ? 0 : mMarginX;
                mMarginX = mMarginX <= -mMenuWidth ? -mMenuWidth : mMarginX;

                mMenuParams.leftMargin = (int) mMarginX;
                llMenu.setLayoutParams(mMenuParams);
                mDownX = mMoveX;//更新手指按下的位置
                break;
            case MotionEvent.ACTION_UP:
                float upX = event.getX();
                //要实现什么样的效果?
                //手指停止的时候,界面滑动到某个位置,根据这个位置来判断是否显示menu
                //手指停止的位置,手指滑动的方向来确定后续操作。
                //根据down的位置和up的位置可以判断方向,根据leftMargin来判断位置
                velocityTracker.computeCurrentVelocity(1000);//计算移动
                float xVelocity = Math.abs(velocityTracker.getXVelocity());
                int leftMargin = mMenuParams.leftMargin;
                int leftMarginABS = Math.abs(leftMargin);
                Log.e("MainActivity", "xVelocity=" + xVelocity);
                if (mFirstDownX > upX && leftMargin <= 0 && leftMargin > -mMenuWidth) {//左滑  并且能够进行左滑
                    if (leftMarginABS > mMenuWidth / 2 || xVelocity > maxVelocity) {//左边显示的过多
                        Log.e("MainActivity", "左滑 xVelocity > maxVelocity=" + (xVelocity > maxVelocity));
                        showContent();
                    } else if (leftMarginABS < mMenuWidth / 2) {
                        showMenu();
                    }
                } else {//右滑
                    if (mFirstDownX < upX && leftMargin < 0 && leftMargin >= -mMenuWidth) {//保证能进行右滑
                        if (leftMarginABS <= mMenuWidth / 2 || xVelocity > maxVelocity) {//左边显示的少
                            Log.e("MainActivity", "右滑 xVelocity > maxVelocity=" + (xVelocity > maxVelocity));
                            showMenu();
                        } else if (leftMarginABS > mMenuWidth / 2) {
                            showContent();
                        }
                    }
                }
                break;
        }
        return true;
    }

最终效果:

【Touch】触摸事件onTouch_第4张图片

你可能感兴趣的:(android)