Android未读消息拖动气泡示例代码详解(附源码)
前言
拖动清除未读消息可以说在很多应用中都很常见,也被用户广泛接受。本文是一个可以供参考的Demo,希望能有帮助。
提示:以下是本篇文章正文内容,下面案例可供参考
最终效果图及思路
实现关键:
气泡中间的两条边,分别是以ab,cd为数据点,G为控制点的贝塞尔曲线。
步骤:
绘制圆背景以及文本;连接情况绘制贝塞尔曲线;另外端点绘制一个圆
关键代码
1.定义,初始化等
状态:静止、连接、分离、消失
在onSizeChanged中初始化状态,固定气泡以及可动气泡的圆心
代码如下(示例):
@Override protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){ super.onSizeChanged(w,h,oldw,oldh); init(w,h); } privatevoidinit(intw,inth){ mBubbleState=BUBBLE_STATE_DEFAULT; //设置固定气泡圆心初始坐标 if(mBubFixedCenter==null){ mBubFixedCenter=newPointF(w/2,h/2); }else{ mBubFixedCenter.set(w/2,h/2); } //设置可动气泡圆心初始坐标 if(mBubMovableCenter==null){ mBubMovableCenter=newPointF(w/2,h/2); }else{ mBubMovableCenter.set(w/2,h/2); } }
2.onDraw中绘制包括三样绘制
第一样:静止,连接,分离状态都需要绘制圆背景以及文本:
//静止,连接,分离状态都需要绘制圆背景以及文本 if(mBubbleState!=BUBBLE_STATE_DISMISS){ canvas.drawCircle(mBubMovableCenter.x,mBubMovableCenter.y,mBubMovableRadius,mBubblePaint); mTextPaint.getTextBounds(mTextStr,0,mTextStr.length(),mTextRect); canvas.drawText(mTextStr,mBubMovableCenter.x-mTextRect.width()/2,mBubMovableCenter.y+mTextRect.height()/2,mTextPaint); }
第二样:连接状态绘制贝塞尔曲线①。
if(mBubbleState==BUBBLE_STATE_CONNECT){ //绘制静止的气泡 canvas.drawCircle(mBubFixedCenter.x,mBubFixedCenter.y,mBubFixedRadius,mBubblePaint); //计算控制点的坐标 intiAnchorX=(int)((mBubMovableCenter.x+mBubFixedCenter.x)/2); intiAnchorY=(int)((mBubMovableCenter.y+mBubFixedCenter.y)/2); floatsinTheta=(mBubMovableCenter.y-mBubFixedCenter.y)/mDist; floatcosTheta=(mBubMovableCenter.x-mBubFixedCenter.x)/mDist; //D floatiBubFixedStartX=mBubFixedCenter.x-mBubFixedRadius*sinTheta; floatiBubFixedStartY=mBubFixedCenter.y+mBubFixedRadius*cosTheta; //C floatiBubMovableEndX=mBubMovableCenter.x-mBubMovableRadius*sinTheta; floatiBubMovableEndY=mBubMovableCenter.y+mBubMovableRadius*cosTheta; //A floatiBubFixedEndX=mBubFixedCenter.x+mBubFixedRadius*sinTheta; floatiBubFixedEndY=mBubFixedCenter.y-mBubFixedRadius*cosTheta; //B floatiBubMovableStartX=mBubMovableCenter.x+mBubMovableRadius*sinTheta; floatiBubMovableStartY=mBubMovableCenter.y-mBubMovableRadius*cosTheta; mBezierPath.reset(); mBezierPath.moveTo(iBubFixedStartX,iBubFixedStartY); mBezierPath.quadTo(iAnchorX,iAnchorY,iBubMovableEndX,iBubMovableEndY); mBezierPath.lineTo(iBubMovableStartX,iBubMovableStartY); mBezierPath.quadTo(iAnchorX,iAnchorY,iBubFixedEndX,iBubFixedEndY); mBezierPath.close(); canvas.drawPath(mBezierPath,mBubblePaint); }
第三样:消失状态执行爆炸动画
//认为是消失状态,执行爆炸动画 if(mBubbleState==BUBBLE_STATE_DISMISS&&mCurDrawableIndex3.onTouchEvent中
按下:区分静止状态和连接状态
caseMotionEvent.ACTION_DOWN: if(mBubbleState!=BUBBLE_STATE_DISMISS){ mDist=(float)Math.hypot(event.getX()-mBubFixedCenter.x,event.getY()-mBubFixedCenter.y); if(mDist移动:判断是否到了分离状态
caseMotionEvent.ACTION_MOVE: if(mBubbleState!=BUBBLE_STATE_DEFAULT){ mDist=(float)Math.hypot(event.getX()-mBubFixedCenter.x,event.getY()-mBubFixedCenter.y); mBubMovableCenter.x=event.getX(); mBubMovableCenter.y=event.getY(); if(mBubbleState==BUBBLE_STATE_CONNECT){ if(mDist弹起:判断是否已经到了分离状态,分离状态爆炸,未分离反弹
caseMotionEvent.ACTION_UP: if(mBubbleState==BUBBLE_STATE_CONNECT){ //橡皮筋动画 startBubbleRestAnim(); }elseif(mBubbleState==BUBBLE_STATE_APART){ if(mDist<2*mBubbleRadius){ //反弹动画 startBubbleRestAnim(); }else{ //爆炸动画 startBubbleBurstAnim(); } } break;4.反弹和爆炸动画
/** *连接状态下松开手指,执行类似橡皮筋动画 */ privatevoidstartBubbleRestAnim(){ ValueAnimatoranim=ValueAnimator.ofObject(newPointFEvaluator(), newPointF(mBubMovableCenter.x,mBubMovableCenter.y), newPointF(mBubFixedCenter.x,mBubFixedCenter.y)); anim.setDuration(200); anim.setInterpolator(newOvershootInterpolator(5f)); anim.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){ @Override publicvoidonAnimationUpdate(ValueAnimatoranimation){ mBubMovableCenter=(PointF)animation.getAnimatedValue(); invalidate(); } }); anim.addListener(newAnimatorListenerAdapter(){ @Override publicvoidonAnimationEnd(Animatoranimation){ super.onAnimationEnd(animation); mBubbleState=BUBBLE_STATE_DEFAULT; } }); anim.start(); }/** *爆炸动画 */ privatevoidstartBubbleBurstAnim(){ //将气泡改成消失状态 mBubbleState=BUBBLE_STATE_DISMISS; ValueAnimatoranimator=ValueAnimator.ofInt(0,mBurstBitmapsArray.length); animator.setInterpolator(newLinearInterpolator()); animator.setDuration(500); animator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){ @Override publicvoidonAnimationUpdate(ValueAnimatoranimation){ mCurDrawableIndex=(int)animation.getAnimatedValue(); invalidate(); } }); animator.start(); }总结
注:①贝塞尔曲线参考博文
本文完,有需要参考的同学→文中Demo下载地址
本系列文章引导页点击这里
到此这篇关于Android未读消息拖动气泡示例代码详解的文章就介绍到这了,更多相关Android未读消息拖动气泡内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。