美文网首页
GridView的Item按下后纵向滑动收不到ACTION_UP

GridView的Item按下后纵向滑动收不到ACTION_UP

作者: _年少 | 来源:发表于2018-05-31 10:42 被阅读0次

需求是 GridView的Item按下后放大 松手时缩放至原来大小 所以很简单的想到在onTouchEvent方法的 ACTION_DOWNACTION_DOWN 动作中添加相应的代码

@Override
    public boolean onTouchEvent(MotionEvent event) {
        ObjectAnimator scaleX;
        ObjectAnimator scaleY;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //组合动画
                mAnimator.end();
                scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1.1f);
                scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1.1f);
                mAnimator.setDuration(100);
                mAnimator.setInterpolator(new DecelerateInterpolator());
                mAnimator.play(scaleX).with(scaleY);//两个动画同时开始
                mAnimator.start();
                break;
            case MotionEvent.ACTION_UP:
                mAnimator.end();
                scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1f);
                scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1f);
                mAnimator.setDuration(100);
                mAnimator.setInterpolator(new DecelerateInterpolator());
                mAnimator.play(scaleX).with(scaleY);//两个动画同时开始
                mAnimator.start();
                break;
        }
        return super.onTouchEvent(event);
    }

本以为两段代码的事情 运行到设备后发现两段代码还是不够

image.png
正常点击后松开Item可以执行到ACTION_DOWNACTION_UP动作 但是当按下后上下滑动就只能执行到ACTION_DOWN动作结果就是如图中Item无法缩放至原始大小

既然执行了ACTION_UP没有执行ACTION_DOWN所以猜测是触摸事件被父控件的onInterceptTouchEvent方法给拦截 则在代码中添加ACTION_CANCEL动作代码

case MotionEvent.ACTION_CANCEL:
                mAnimator.end();
                scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1f);
                scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1f);
                mAnimator.setDuration(100);
                mAnimator.setInterpolator(new DecelerateInterpolator());
                mAnimator.play(scaleX).with(scaleY);//两个动画同时开始
                mAnimator.start();
                //按钮弹起逻辑
                break;

问题解决

然后猜测是触摸事件被父控件的onInterceptTouchEvent方法给拦截 查代码证实下

image.png
先找到GridView中没有onInterceptTouchEvent方法,点击进入父类AbsListView中继续查看
image.png
从方法列表中找出onInterceptTouchEvent方法的ACTION_MOVE动作,代码如下
        case MotionEvent.ACTION_MOVE: {
            switch (mTouchMode) {
            case TOUCH_MODE_DOWN:
                int pointerIndex = ev.findPointerIndex(mActivePointerId);
                if (pointerIndex == -1) {
                    pointerIndex = 0;
                    mActivePointerId = ev.getPointerId(pointerIndex);
                }
                final int y = (int) ev.getY(pointerIndex);
                initVelocityTrackerIfNotExists();
                mVelocityTracker.addMovement(ev);
                if (startScrollIfNeeded((int) ev.getX(pointerIndex), y, null)) {
                    return true;
                }
                break;
            }
            break;
        }

代码中看出 如果startScrollIfNeeded((int) ev.getX(pointerIndex), y, null)返回true则拦截事件,点击找到startScrollIfNeeded代码如下

private boolean startScrollIfNeeded(int x, int y, MotionEvent vtev) {
        // Check if we have moved far enough that it looks more like a
        // scroll than a tap
        final int deltaY = y - mMotionY;
        final int distance = Math.abs(deltaY);
        final boolean overscroll = mScrollY != 0;
        if ((overscroll || distance > mTouchSlop) &&
                (getNestedScrollAxes() & SCROLL_AXIS_VERTICAL) == 0) {
            createScrollingCache();
            if (overscroll) {
                mTouchMode = TOUCH_MODE_OVERSCROLL;
                mMotionCorrection = 0;
            } else {
                mTouchMode = TOUCH_MODE_SCROLL;
                mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
            }
            removeCallbacks(mPendingCheckForLongPress);
            setPressed(false);
            final View motionView = getChildAt(mMotionPosition - mFirstPosition);
            if (motionView != null) {
                motionView.setPressed(false);
            }
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            // Time to start stealing events! Once we've stolen them, don't let anyone
            // steal from us
            final ViewParent parent = getParent();
            if (parent != null) {
                parent.requestDisallowInterceptTouchEvent(true);
            }
            scrollIfNeeded(x, y, vtev);
            return true;
        }

        return false;
    }

从方法中可以看出GridView是结束滑动的并且滑动方向是纵向则返回true

if ((overscroll || distance > mTouchSlop) &&
                (getNestedScrollAxes() & SCROLL_AXIS_VERTICAL) == 0) 

工作好几年 一直没怎么有写东西的习惯,所以对写东西也越来越生疏,改变总是痛苦的,但改变也是必要的
以后会养成写东西 记东西的习惯 记下自己以前 现在 以后在开发中遇到的问题

相关文章

网友评论

      本文标题:GridView的Item按下后纵向滑动收不到ACTION_UP

      本文链接:https://www.haomeiwen.com/subject/yrnfsftx.html