软件编程
位置:首页>> 软件编程>> Android编程>> Android仿QQ圆形头像个性名片

Android仿QQ圆形头像个性名片

作者:cj_286  发布时间:2021-08-24 02:40:46 

标签:Android,QQ,圆形头像,个性名片

先看看效果图:

Android仿QQ圆形头像个性名片

中间的圆形头像和光环波形讲解请看:https://www.jb51.net/article/96508.htm
周围的气泡布局,因为布局RatioLayout是继承自ViewGroup,所以布局layout就可以根据自己的需求来布局其子view,view.layout(int l,int t,int r,int b);用于布局子view在父ViewGroup中的位置(相对于父容器),所以在RatioLayout中计算所有子view的left,top,right,bottom。那么头像的周围的气泡view是如何计算它的left,top,right,bottom的呢,这些气泡view是坐落在头像外围的圆环上,只要知道这个圆环的半径,然后再根据气泡的个数,计算每个气泡之间的角度,半径加角度就可以计算每个气泡坐落的位置。


/**
* 计算气泡的布局位置
* @param textViews
*/
private void calculateRatioFrame(List<BubbleView> textViews){
if(textViews.size() == 0) return;
mRatioFrameList.clear();

double angle = 0;//记录每个气泡的角度,正上方的为0°
double grad = Math.PI * 2 / textViews.size();//梯度,每个TextView之间的角度 (Math.PI 是数学中的90°)
double rightAngle = Math.PI / 2;//一圈为360°,一共四个方向,每个方向90°,我们按照小于等于90°来计算,然后再放到相应的方向上

//cx,cy是容器的中心点,也是圆形头像的中心点,计算气泡的位置就是已cx,cy为基准来计算的
int cx = mWidth / 2;//容器中心x坐标
int cy = mHeight / 2;//容器中心y坐标

int radius = mMinSize / 2 / 2 / 2 + mMinSize / 2 / 2 ;//动态气泡的组成圆的半径

int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
int a = 0,b = 0;//a是基于cx的偏移量,b是基于cy的偏移量,
//int r = mMinSize / 6 / 2;//气泡半径
for (int i = 0; i < textViews.size(); i++) {
int r = textViews.get(i).getMeasuredWidth() / 2;//计算得来//固定死的mMinSize / 6 / 2;//气泡半径
if(angle >= 0 && angle < rightAngle){ //0 - 90度是计算偏移量
//保持角度在 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;

}else if(angle >= rightAngle && angle < rightAngle * 2){ // 90 - 180
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;

}else if(angle >= rightAngle * 2 && angle < rightAngle * 3){ // 180 - 270
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;

}else if(angle >= rightAngle * 3 && angle < rightAngle * 4){ //270 - 360
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(new RatioFrame(left, top, right,bottom,angle));
//角度再加一个梯度值
angle += grad;

}
}

计算好气泡的布局left,  top, right,bottom,下面就开始布局这起气泡,布局中的代码就简单的多了


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(mImageView == null) return;

int width = mImageView.getMeasuredWidth();//计算圆形头像的宽
int height = mImageView.getMeasuredHeight();//计算圆形头像的高
//计算圆形头像的left, top, right,bottom
int left = mWidth / 2 - width / 2;
int top = mHeight / 2 - height / 2;
int right = mWidth / 2 + width / 2;
int bottom = mHeight / 2 + height / 2;
//开始布局
mImageView.layout(left,top,right,bottom);
//布局爱心动画
for (int i = 0; i < mLoveXinList.size(); i++) {
ImageView imageView = 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 (int i = 0; i < mTextViews.size(); i++) {

TextView textView = mTextViews.get(i);

//RatioFrame ratioFrame = mRatioFrameList.get(i);//无动画时使用
//有动画的时候,执行期间left, top, right,bottom都在变
if(mCurrentRatioFrameList != null){
//ValueAnimator执行动画是所产生的所有气泡left, top, right,bottom
RatioFrame ratioFrame = mCurrentRatioFrameList.get(i);
textView.layout(ratioFrame.mLeft,ratioFrame.mTop,ratioFrame.mRight,ratioFrame.mBottom);
}

}

}
0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com