高仿QQ的个性名片.docx
- 文档编号:3763041
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:14
- 大小:88.16KB
高仿QQ的个性名片.docx
《高仿QQ的个性名片.docx》由会员分享,可在线阅读,更多相关《高仿QQ的个性名片.docx(14页珍藏版)》请在冰豆网上搜索。
高仿QQ的个性名片
高仿QQ的个性名片
周围的气泡布局,因为布局RatioLayout是继承自ViewGroup,所以布局layout就可以根据自己的需求来布局其子view,view.layout(intl,intt,intr,intb);用于布局子view在父ViewGroup中的位置(相对于父容器),所以在RatioLayout中计算所有子view的left,top,right,bottom。
那么头像的周围的气泡view是如何计算它的left,top,right,bottom的呢,这些气泡view是坐落在头像外围的圆环上,只要知道这个圆环的半径,然后再根据气泡的个数,计算每个气泡之间的角度,半径加角度就可以计算每个气泡坐落的位置。
[java]viewplaincopy
/**
*计算气泡的布局位置
*@paramtextViews
*/
privatevoidcalculateRatioFrame(List
if(textViews.size()==0)return;
mRatioFrameList.clear();
doubleangle=0;//记录每个气泡的角度,正上方的为0°
doublegrad=Math.PI*2/textViews.size();//梯度,每个TextView之间的角度(Math.PI是数学中的90°)
doublerightAngle=Math.PI/2;//一圈为360°,一共四个方向,每个方向90°,我们按照小于等于90°来计算,然后再放到相应的方向上
//cx,cy是容器的中心点,也是圆形头像的中心点,计算气泡的位置就是已cx,cy为基准来计算的
intcx=mWidth/2;//容器中心x坐标
intcy=mHeight/2;//容器中心y坐标
intradius=mMinSize/2/2/2+mMinSize/2/2;//动态气泡的组成圆的半径
intleft=0;
inttop=0;
intright=0;
intbottom=0;
inta=0,b=0;//a是基于cx的偏移量,b是基于cy的偏移量,
//intr=mMinSize/6/2;//气泡半径
for(inti=0;i intr=textViews.get(i).getMeasuredWidth()/2;//计算得来//固定死的mMinSize/6/2;//气泡半径 if(angle>=0&&angle //保持角度在0-90 a=(int)(radius*Math.sin(Math.abs(angle%rightAngle))); b=(int)(radius*Math.cos(Math.abs(angle%rightAngle))); left=cx+a-r;//cx+a为气泡的中心点,要想得到left,还需减去半径r top=cy-b-r; right=left+2*r; bottom=top+2*r; }elseif(angle>=rightAngle&&angle a=(int)(radius*Math.sin(Math.abs(angle%rightAngle))); b=(int)(radius*Math.cos(Math.abs(angle%rightAngle))); left=cx+b-r; top=cy+a-r; right=left+2*r; bottom=top+2*r; }elseif(angle>=rightAngle*2&&angle a=(int)(radius*Math.sin(Math.abs(angle%rightAngle))); b=(int)(radius*Math.cos(Math.abs(angle%rightAngle))); left=cx-a-r; top=cy+b-r; right=left+2*r; bottom=top+2*r; }elseif(angle>=rightAngle*3&&angle a=(int)(radius*Math.sin(Math.abs(angle%rightAngle))); b=(int)(radius*Math.cos(Math.abs(angle%rightAngle))); left=cx-b-r; top=cy-a-r; right=left+2*r; bottom=top+2*r; } //将计算好的left,top,right,bottom,angle保存起来 mRatioFrameList.add(newRatioFrame(left,top,right,bottom,angle)); //角度再加一个梯度值 angle+=grad; } } 计算好气泡的布局left,top,right,bottom,下面就开始布局这起气泡,布局中的代码就简单的多了 [java]viewplaincopy @Override protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){ if(mImageView==null)return; intwidth=mImageView.getMeasuredWidth();//计算圆形头像的宽 intheight=mImageView.getMeasuredHeight();//计算圆形头像的高 //计算圆形头像的left,top,right,bottom intleft=mWidth/2-width/2; inttop=mHeight/2-height/2; intright=mWidth/2+width/2; intbottom=mHeight/2+height/2; //开始布局 mImageView.layout(left,top,right,bottom); //布局爱心动画 for(inti=0;i ImageViewimageView=mLoveXinList.get(i); left=mWidth/2+width/4-imageView.getMeasuredWidth()/2; bottom=mHeight/2+height/3; top=bottom-imageView.getMeasuredHeight(); right=left+imageView.getMeasuredWidth(); imageView.layout(left,top,right,bottom); } //布局所有气泡 for(inti=0;i TextViewtextView=mTextViews.get(i); //RatioFrameratioFrame=mRatioFrameList.get(i);//无动画时使用 //有动画的时候,执行期间left,top,right,bottom都在变 if(mCurrentRatioFrameList! =null){ //ValueAnimator执行动画是所产生的所有气泡left,top,right,bottom RatioFrameratioFrame=mCurrentRatioFrameList.get(i); textView.layout(ratioFrame.mLeft,ratioFrame.mTop,ratioFrame.mRight,ratioFrame.mBottom); } } } 好了,静态的气泡排版到这里就好了,下面的问题是,展开时如何使气泡从中心点,以弧形的路径展开,并且气泡的大小也是由小到大变化。 这里就用到的动画类ValueAnimator和ScaleAnimation,详解请参考: 向外展开的效果我们可以使用view.layout()不断的重新布局气泡view,让其产生一个平移的效果,下面的一个问题就是如何计算平移轨道上面的left,top,right,bottom,然后重新请求布局就可以了,那么下面就解决如何计算这个轨迹,分析 弧形轨迹计算,其实就是在直线轨迹的基础上加上偏移量(moveX和moveY),就形成了弧形轨迹,直线轨迹很好计算,关键的就是这个偏移量,因为在首位的偏移量小,而在中间的偏移量大,且在不同的方向上,moveX和moveY的值的正负也不一样。 偏移的距离因为是由小到大再由大到小,所以我们用二次函数(-2*Math.pow(fraction,2)+2*fraction)来计算距离,用此二次函数得到的值乘以一个设定的最大值,这个最大值的就会是由小到大再由大到小的变化,然后再用不同的角度来计算它的正负 [java]viewplaincopy if(endRatioFrame.mAngle>0&&endRatioFrame.mAngle<=rightAngle){//(0 moveX=(int)(temp*Math.abs(Math.cos(endRatioFrame.mAngle)));//上移就应该在原本的轨迹上减去moveX moveY=(int)(temp*Math.abs(Math.sin(endRatioFrame.mAngle))); }elseif(endRatioFrame.mAngle>rightAngle&&endRatioFrame.mAngle<=rightAngle*2){//(90 moveX=(int)(-temp*Math.abs(Math.cos(endRatioFrame.mAngle))); moveY=(int)(temp*Math.abs(Math.sin(endRatioFrame.mAngle))); }elseif(endRatioFrame.mAngle>rightAngle*2&&endRatioFrame.mAngle<=rightAngle*3){//(180 moveX=(int)(-temp*Math.abs(Math.cos(endRatioFrame.mAngle))); moveY=(int)(-temp*Math.abs(Math.sin(endRatioFrame.mAngle))); }elseif(endRatioFrame.mAngle>rightAngle*3&&endRatioFrame.mAngle<=rightAngle*4||endRatioFrame.mAngle==0){//(270 moveX=(int)(temp*Math.abs(Math.cos(endRatioFrame.mAngle))); moveY=(int)(-temp*Math.abs(Math.sin(endRatioFrame.mAngle))); } 根据三角函数的变化值,上面的代码可以简化为 [java]viewplaincopy moveX=(int)(temp*Math.cos(endRatioFrame.mAngle)); moveY=(int)(temp*Math.sin(endRatioFrame.mAngle)); 通过上面的计算公式逻辑,就可以得到气泡展开时的类型估算器的实现类,退出气泡就将逻辑反一下就可以了 [java]viewplaincopy packagecom.cj.dynamicavatarview.ratio; importandroid.animation.TypeEvaluator; importandroid.content.Context; importandroid.util.TypedValue; importjava.util.ArrayList; importjava.util.List; /** *Createdbychenjon2016/10/19. */ publicclassEnterRatioFrameEvaluatorimplementsTypeEvaluator{ publicstaticfinalintOFFSET_DISTANCE=80; privateContextmContext; privateintmOffsetDistance; publicEnterRatioFrameEvaluator(Contextcontext){ this.mContext=context; mOffsetDistance=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,OFFSET_DISTANCE,mContext.getResources().getDisplayMetrics()); } @Override publicObjectevaluate(floatfraction,ObjectstartValue,ObjectendValue){ List List List for(inti=0;i RatioFrameendRatioFrame=endRatioFrameList.get(i); RatioFramestartRatioFrame=startRatioFrameList.get(i); //计算left,top,right,bottom doublet=(-2*Math.pow(fraction,2)+2*fraction);//倾斜变化率 inttemp=(int)((mOffsetDistance)*t); doublerightAngle=Math.PI/2; intmoveX=0,moveY=0; //让气泡上、下、左、右平移,形成弧度的平移路线 moveX=(int)(temp*Math.cos(endRatioFrame.mAngle)); moveY=(int)(temp*Math.sin(endRatioFrame.mAngle)); //重新得到left,top,right,bottom intleft=(int)(startRatioFrame.mLeft+((endRatioFrame.mLeft-startRatioFrame.mLeft)*fraction)-moveX); inttop=(int)(startRatioFrame.mTop+((endRatioFrame.mTop-startRatioFrame.mTop)*fraction)-moveY); intright=(int)(startRatioFrame.mRight+((endRatioFrame.mRight-startRatioFrame.mRight)*fraction)-moveX); intbottom=(int)(startRatioFrame.mBottom+((endRatioFrame.mBottom-startRatioFrame.mBottom)*fraction)-moveY); ratioFrameList.add(newRatioFrame(left,top,right,bottom)); } returnratioFrameList; } } 下面就可以用ValueAnimator来实现弧形平移轨迹了 [java]viewplaincopy ValueAnimatormAnimatorEnetr=ValueAnimator.ofObject(newEnterRatioFrameEvaluator(getContext()),getRatioFrameCenterList(mRatioFrameCenter,mRatioFrameList),mRatioFrameList); mAnimatorEnetr.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){ @Override publicvoidonAnimationUpdate(ValueAnimatoranimation){ //获取新的布局值 mCurrentRatioFrameList=(List //请求重新布局 requestLayout(); } }); mAnimatorEnetr.setDuration(OPEN_BUBBLE_TIME); mAnimatorEnetr.start(); 好了,从中心点向外展开的弧形动画到这就实现了,然后再加上缩放的动画就可以了,缩放的动画使用View动画就可以实现。 [java]viewplaincopy /** *气泡由小到大缩放 *@paramtextViews */ privatevoidscaleSmallToLarge(List //以view中心为缩放点,由初始状态缩小到看不间 ScaleAnimationanimation=newScaleAnimation( 0.0f,1.0f,//一点点变小知道看不见为止 0.0f,1.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f//中间缩放 ); animation.setDuration(OPEN_BUBBLE_TIME);//要和平移的时间一致 for(inti=0;i //再执行动画 textViews.get(i).startAnimation(animation); } } 下面解决的就是展开后,气泡开始浮动,点击气泡后停止浮动,滑动手指的之后气泡跟着手指移动,松开手指后气泡返回到原来的位置,返回时的动画效果和气泡展开的动画效果非常的类似,气泡跟着手指移动也很好实现,只需要将气泡view设置onTouch事件,再onTouch中计算滑动的距离,然后重新view.layout()就可以了,所以这里我们解决浮动问题就可以了。 浮动是不规则的,并且浮动的距离和速度也是不一样的,我用View动画实现的效果不是很好,然后就改用了属性动画来实现。 只需要将view平移x轴和y轴,让其平移的距离和时间都不同,看上去就像无规则的移动,让其反复的做这样的平移就可以实现浮动的效果。 [java]viewplaincopy /** *给指定的View设置浮动效果 *@paramview *@return */ privateAnimatorSetsetAnimFloat(Viewview){ List //getRandomDp()得到一个随机的值 ObjectAnimatortranslationXAnim=ObjectAnimator.ofFloat(view,"translationX",0f,getRandomDp(),getRandomDp(),0); translationXAnim.setDuration(getRandomTime()); translationXAnim.setRepeatCount(ValueAnimator.INFINITE);//无限循环 translationXAnim.setRepeatMode(ValueAnimator.I
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- QQ 个性 名片
![提示](https://static.bdocx.com/images/bang_tan.gif)