新版手机QQ5.+上新增了一种“一键退朝”的功能,即在页面上的红点可进行拖拽消除。按照设计思路在Android上模仿手Q实现下拖拽的过程。
整体的思路,封装好一个view。在界面上找到四个点,即框出手势拖动点与红点之间的范围,利用贝塞尔曲线修饰边框,计算红点和手势拖动点间的距离,判断红点的消除与回弹。
借用下设计图:
首先确定以红点为坐标原点,在坐标上所要计算的就是p1, p2, p3, p4四个点,其中..为贝塞尔曲线,在p1p2和p3p4之间需要绘制半径为R和r的圆。
接下来需要的就是在拖动过程中计算(0,0)和(x0, y0)两点间的距离,通过距离控制贝塞尔曲线的弧度和圆的大小,实现模拟现实生活中弹性效果。
在代码中通过Path来控制p1, p2, p3, p4四个点所围成的范围,并填充相应地色值:
1.确定四个点,这里简单地将两个圆起始半径设置相等
01 |
float x1 = startX - offsetX;
|
02 |
float y1 = startY + offsetY;
|
04 |
float x2 = x - offsetX;
|
05 |
float y2 = y + offsetY;
|
07 |
float x3 = x + offsetX;
|
08 |
float y3 = y - offsetY;
|
10 |
float x4 = startX + offsetX;
|
11 |
float y4 = startY - offsetY;
|
15 |
path.quadTo(anchorX, anchorY, x2, y2); |
17 |
path.quadTo(anchorX, anchorY, x4, y4); |
2.填充范围和绘制圆形:
1 |
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY); |
2 |
canvas.drawPath(path, paint); |
3 |
canvas.drawCircle(startX, startY, radius, paint); |
4 |
canvas.drawCircle(x, y, radius, paint); |
3.在调用super.onDraw(canvas);方法绘制在canvas层上面的消息点图标imageView
通过在代码中的onTouchEvent方法进行控制触摸点的相应位置,实现拖动的效果。
02 |
public boolean onTouchEvent(MotionEvent event) {
|
03 |
if (event.getAction() == MotionEvent.ACTION_DOWN){
|
05 |
Rect rect = new Rect();
|
06 |
int [] location = new int [ 2 ];
|
07 |
tipImageView.getDrawingRect(rect);
|
08 |
tipImageView.getLocationOnScreen(location);
|
09 |
rect.left = location[ 0 ];
|
10 |
rect.top = location[ 1 ];
|
11 |
rect.right = rect.right + location[ 0 ];
|
12 |
rect.bottom = rect.bottom + location[ 1 ];
|
13 |
if (rect.contains(( int )event.getRawX(), ( int )event.getRawY())){
|
16 |
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL){
|
18 |
tipImageView.setX(startX - tipImageView.getWidth()/ 2 );
|
19 |
tipImageView.setY(startY - tipImageView.getHeight()/ 2 );
|
23 |
return super .onTouchEvent(event);
|
25 |
anchorX = (event.getX() + startX)/ 2 ;
|
26 |
anchorY = (event.getY() + startY)/ 2 ;
|
4.拖动过程中计算两个圆心之间的距离,通过圆心间的距离调整圆心为(0, 0)圆的半径大小
1 |
float distance = ( float ) Math.sqrt(Math.pow(y-startY, 2 ) + Math.pow(x-startX, 2 ));
|
2 |
radius = -distance/ 15 +DEFAULT_RADIUS;
|
用新的半径去绘制(0, 0)的圆,这样随着距离的增加,圆相应变小就给人如同快要沾不住黏黏的感觉。
5.距离超过设定的最大范围,则设置为红点挣脱状态,如果手指抬起,则开始播放相应爆炸动画。
1 |
exploredImageView.setVisibility(View.VISIBLE); |
2 |
exploredImageView.setImageResource(R.drawable.tip_anim); |
3 |
((AnimationDrawable) exploredImageView.getDrawable()).stop(); |
4 |
((AnimationDrawable) exploredImageView.getDrawable()).start(); |
6.在Activity布局中引用相应封装好的view即可。
1 |
< github.chenupt.bezier.BezierView |
2 |
android:layout_width = "match_parent" |
3 |
android:layout_height = "match_parent" |
4 |
android:background = "@android:color/transparent" />
|
最开始设想的view在类似于红点范围的一个控件,但是这样实现就达不到拖动到父类控件的范围之外,比如拖动红点超过页签布局范围时,红点则无法绘制。因此在QQ的消息列表中是将其设置相应全屏的一个view。背景为截图的上个背景,这样在最上一层实则只有红点的控件。这样就能相应地拖动红点到屏幕的各个位置。所以才会在红点列表爆照动画结束之前页签是不可点击,并且拖动红点的时候列表数据没有刷新。
分享到:
相关推荐
手机QQ红点消除的功能大家应该印象很深,我一直奇怪微信为什么不跟进这个功能,毕竟消息太多。 功能图如下: ![这里写图片描述](http://img.blog.csdn.net/20151118101649390) 简单的功能描述是这样的:**新消息...
android仿qq拖拽小红点demo qq小红点可以拖动相信大家已经玩过了,用户体验也非常的好.效果很不错 思路:小红点是可以拖拽到原来的控件外面的, 那么就在点击下去之后在它的最外层添加一个覆盖层来在小红点所在位置...
仿qq拖拽红点效果
一款仿QQ,拖拽消除红点的自定义View,可以很简单的进行使用,还有另一款http://jcodecraeer.com/a/opensource/2015/0203/2406.html,也可以实现同样的效果
unity实现防QQ红点拖动效果,拖动,还原,回调等,完美实现。
Android带拖拽效果的红点提示控件 DragIndicatorView
仿QQ消息提醒小红点拖拽粘连效果 [注意:本资源来自网络,如有侵权,请联系我删除,谢谢。]
仿QQ可拖动小红点,直接将util以及自定义view的文件拷入到项目中即可,使用方法在MainActivity中
实现QQ消息提醒的小红点,可拖动
博客《自定义控件三部曲之绘图篇(十五)——QQ红点拖动删除效果实现(基本原理篇)》对应源码,博客地址:http://blog.csdn.net/harvic880925/article/details/51615221
安卓消息小红点,直接引用jar包,可自定义背景颜色,字体颜色,样式美观。
腾讯QQ有那种红点拖动效果,今天就来实现一个简单的自定义View拖动效果,再回到原处,并非完全仿QQ红点拖动
自定义view高仿QQ消息小红点,本资源为Android项目,请用Android Studio打开。
红点拖拽 支持拖拽黏滞效果, 支持松手取消, 黏滞效果距离偏移可控, 完成距离偏移可控, github: https://github.com/Modool/EVRElasticViewReference
iOS 数字红点角标仿QQ拖拽清除,使用方便简单只需一行代码,支持代码和xib,支持约束和frame
新消息/未接来电/未读消息/新通知圆球红点提示
Android-NavMenu-master一个底部导航栏, 实现了显示未读消息数, 显示红点等效果的封装
编译环境vs2015,只是实现了在普通的Button控件上显示类似安卓和Ios上的右上角红点提示。具体的介绍请参照本人博客当中的相关文章。