新版手机QQ5.+上新增了一种“一键退朝”的功能,即在页面上的红点可进行拖拽消除。在[知乎](http://www.zhihu.com/question/26382740)上可参考红点的设计过程。按照设计思路在Android上模仿手Q实现下拖拽的过程。
代码地址:https://github.com/chenupt/BezierDemo
效果图:

接下来需要的就是在拖动过程中计算(0,0)和(x0, y0)两点间的距离,通过距离控制贝塞尔曲线的弧度和圆的大小,实现模拟现实生活中弹性效果。
在代码中通过Path来控制p1, p2, p3, p4四个点所围成的范围,并填充相应地色值:
1.确定四个点,这里简单地将两个圆起始半径设置相等
float x1 = startX - offsetX;
float y1 = startY + offsetY;
float x2 = x - offsetX;
float y2 = y + offsetY;
float x3 = x + offsetX;
float y3 = y - offsetY;
float x4 = startX + offsetX;
float y4 = startY - offsetY;
path.reset();
path.moveTo(x1, y1);
path.quadTo(anchorX, anchorY, x2, y2);
path.lineTo(x3, y3);
path.quadTo(anchorX, anchorY, x4, y4);
path.lineTo(x1, y1);2.填充范围和绘制圆形:
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY); canvas.drawPath(path, paint); canvas.drawCircle(startX, startY, radius, paint); canvas.drawCircle(x, y, radius, paint);3.在调用super.onDraw(canvas);方法绘制在canvas层上面的消息点图标imageView
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
// 判断触摸点是否在tipImageView中
Rect rect = new Rect();
int[] location = new int[2];
tipImageView.getDrawingRect(rect);
tipImageView.getLocationOnScreen(location);
rect.left = location[0];
rect.top = location[1];
rect.right = rect.right + location[0];
rect.bottom = rect.bottom + location[1];
if (rect.contains((int)event.getRawX(), (int)event.getRawY())){
isTouch = true;
}
}else if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL){
isTouch = false;
tipImageView.setX(startX - tipImageView.getWidth()/2);
tipImageView.setY(startY - tipImageView.getHeight()/2);
}
invalidate();
if(isAnimStart){
return super.onTouchEvent(event);
}
anchorX = (event.getX() + startX)/2;
anchorY = (event.getY() + startY)/2;
x = event.getX();
y = event.getY();
return true;
}
4.拖动过程中计算两个圆心之间的距离,通过圆心间的距离调整圆心为(0, 0)圆的半径大小
float distance = (float) Math.sqrt(Math.pow(y-startY, 2) + Math.pow(x-startX, 2)); radius = -distance/15+DEFAULT_RADIUS;用新的半径去绘制(0, 0)的圆,这样随着距离的增加,圆相应变小就给人如同快要沾不住黏黏的感觉。
5.距离超过设定的最大范围,则设置为红点挣脱状态,如果手指抬起,则开始播放相应爆炸动画。
exploredImageView.setVisibility(View.VISIBLE); exploredImageView.setImageResource(R.drawable.tip_anim); ((AnimationDrawable) exploredImageView.getDrawable()).stop(); ((AnimationDrawable) exploredImageView.getDrawable()).start();
<github.chenupt.bezier.BezierView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" />也许是还有更好地实现方式,欢迎大家进行交流。
代码地址:https://github.com/chenupt/BezierDemo
QQ:753785666
Email:chenupt@gmail.com
原文地址:http://blog.csdn.net/chenupt/article/details/41478303