需求是 GridView的Item按下后放大 松手时缩放至原来大小 所以很简单的想到在onTouchEvent方法的 ACTION_DOWN 和 ACTION_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);
}
本以为两段代码的事情 运行到设备后发现两段代码还是不够

正常点击后松开Item可以执行到ACTION_DOWN和ACTION_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方法给拦截 查代码证实下

先找到GridView中没有onInterceptTouchEvent方法,点击进入父类AbsListView中继续查看

从方法列表中找出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)
工作好几年 一直没怎么有写东西的习惯,所以对写东西也越来越生疏,改变总是痛苦的,但改变也是必要的
以后会养成写东西 记东西的习惯 记下自己以前 现在 以后在开发中遇到的问题
网友评论