可拖拽控件
长时间没有更新blog了,由于最近所做的项目涉及比较多的用户界面操作,现在抽空更新一波。这个blog主要处理是拖动图片到另外一个位置来替换图片的操作。如果位置不正确就会回弹回去。先看看效果图:
收到这个需求的时候第一想法是监听手指在屏幕中的操作,来实时获取手指所在屏幕的坐标,进行实时更新被拖动图的位置,但这种做法就会影响到页面中其它按钮的点击事件了。如果处理点击冲突事件,就记录被拖动图的区域再处理ontouch方法,这样就需要计算的成本很大了。
另外一种想法是,直接监听被拖动图的触摸事件,手指不停的移动,控件不停的改变位置,这种想法似乎更合理,只是要记录下最初位置,最后用平移动画要回去。思路整理清楚了,剩下就是代码的编写。
先处理的是onTouch方法:这里就是对被拖动控件的不断改变位置
@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onAnimationEnd(Animator animation) {mCallbackInternal.onRecovered();}});anim.start();}
最后收尾就写一个接口回调,回调给页面,丢给页面正确拖动到位置的后续操作。
demo下载链接:https://download.csdn.net/download/greatdaocaoren/12529457
标签:
相关文章
-
无相关信息