十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
收到这个需求的时候第一想法是监听手指在屏幕中的操作,来实时获取手指所在屏幕的坐标,进行实时更新被拖动图的位置,但这种做法就会影响到页面中其它按钮的点击事件了。如果处理点击冲突事件,就记录被拖动图的区域再处理ontouch方法,这样就需要计算的成本很大了。
10年积累的成都做网站、成都网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计后付款的网站建设流程,更有东兴免费网站建设让你可以放心的选择与我们合作。
另外一种想法是,直接监听被拖动图的触摸事件,手指不停的移动,控件不停的改变位置,这种想法似乎更合理,只是要记录下最初位置,最后用平移动画要回去。思路整理清楚了,剩下就是代码的编写。
先处理的是onTouch方法:这里就是对被拖动控件的不断改变位置
@Override public boolean onTouch(View v, MotionEvent event) { //如果长按拖动 加上这句 // if (!isLongClicked) return false; switch (event.getAction()) { case MotionEvent.ACTION_MOVE: { // 1. 添加到 Window 中 if (!dragDeleteView.isAttachedToWindow()) { dragDeleteView.bindAnchorView(anchorView); wm.addView(dragDeleteView, params); v.getParent().requestDisallowInterceptTouchEvent(true); v.setVisibility(View.INVISIBLE); } // 2. 更新坐标位置 dragDeleteView.updateFingerPoint(event.getRawX(), event.getRawY()); break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: { if (dragDeleteView.isOverThresholdHeight()) { wm.removeView(dragDeleteView); callback.onDelete(); } else { dragDeleteView.recover(); } v.getParent().requestDisallowInterceptTouchEvent(false); isLongClicked = false; break; } } return false; }
再需要的是判断是否超过了阈值,需要获取目标控件的区域,然后需要获取手指所在的x,y值,判断手指是否在目标区域。
/** * 判断是否拖拽超过了的阈值 * * @return */ public boolean isOverThresholdHeight() { final int[] location = new int[2]; dragDeleteView.getLocationOnScreen(location); //获得宽度 int width = dragDeleteView.getMeasuredWidth(); //获得高度 int height = dragDeleteView.getMeasuredHeight(); float imgY = mCurPoint.y + mAnchorBitmap.getHeight() * 0.8f; float imgX = mCurPoint.x + mAnchorBitmap.getWidth() * 0.8f; if (imgX>(location[0])&&(imgX(location[1])&&imgY<(location[1]+height)){ return true; }else { return false; } }
最后就一个属性动画,如果拖动不在目标区域内,那么就回到原来位置,需要向前甩一定值后再回到原来位置。那么就需要用到插值器了,使用OvershootInterpolator就可以了。从手指抬起的位置到被拖动控件的初始位置。
/** * 供 DragDeleteTouchPerformerInternal 内部调用 ** 恢复原先位置 */ private void recover() { final float deltaX = mCurPoint.x - mStartPoint.x; final float deltaY = mCurPoint.y - mStartPoint.y; ValueAnimator anim = ValueAnimator.ofFloat(1f, 0f).setDuration(500); anim.setInterpolator(new OvershootInterpolator()); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurPoint.x = mStartPoint.x + deltaX * (float) animation.getAnimatedValue(); mCurPoint.y = mStartPoint.y + deltaY * (float) animation.getAnimatedValue(); invalidate(); } }); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mCallbackInternal.onRecovered(); } }); anim.start(); }