Android仿QQ圆形头像个性名片
作者:cj_286 发布时间:2021-08-24 02:40:46
标签: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
投稿
猜你喜欢
- 本文实例讲述了Java网络编程实现的简单端口扫描器。分享给大家供大家参考,具体如下:在计算机网络的学习中,不由得觉得这门课的零碎知识点异常之
- Android 集成FlutterFlutter 作为 Google 开源的新一代跨平台、高性能 UI 框架,旨在帮助开发者高效地构建出跨平
- 本文实例讲述了Java基于JDBC实现事务,银行转账及货物进出库功能。分享给大家供大家参考,具体如下:1. 转账业务转账必须执行2个sql语
- 帧率(Frame rate)是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS)或“赫
- 前言最近在研究串口通讯,其中有几个比较重要的概念,RS-232这种适配于上位机和PC端进行连接,RS-232只限于PC串口和设备间点对点的通
- Commons Beanutils是Apache开源组
- 1、添加spring相关jar包2、配置ehcache jar包。3、添加ehcache mybatis 适配器jar包(在mybatis官
- 本文实例为大家分享了swing登录注册界面展示的具体代码,供大家参考,具体内容如下开发环境:Eclipse Neon.3 Release (
- springboot集成redission及分布式锁的使用1、引入jar包<dependency> &
- pom.xml文件需要的内容<dependency> <groupId>re
- 一 点睛注解若想发挥更大作用,还需借助反射机制之力。通过反射,可以取得一个方法上声明的注解的全部内容。一般有两种需求:1 
- Java类加载器1、BootClassLoader: 用于加载Android Framework层class文件。2、PathClassLo
- FileStream,顾名思义,文件流。流,是字节流。我的理解是,硬盘上存在一个字节流,内存里也有一个字节流,它们是对应的。程序运行时,我们
- 前言:项目是使用Java swing开发,可实现基础数据维护用户登录、系统首页酒店信息管理、主要模块是开房管理、退房管理、房间信息管理、顾客
- 我们在使用SpringBoot进行测试的时候一般是需要加两个注解:@SpringBootTest目的是加载ApplicationContex
- 1、接口:接口与抽象类一样,也是表示某种规则,一旦使用了该规则,就必须实现相关的方法。对于C#语言而言,由于只能继承自一个父类,因此若有多个
- 本文介绍了Maven+Tomcat8 实现自动化部署的方法,分享给大家,具体如下:1.配置tomcat-users.xml首先在Tomcat
- 短网址,忽然一下子就冒出来的东西,长长的一个URL,提交过去,出来就只有短短的一个URL了,看起来似乎挺神奇,其实简单分析一下,明白其中的原
- MyBatis Generator简介MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成
- 在本文中,我们将通过用C#重构一个非常简单的代码示例来解释依赖注入和IoC容器。 简介:依赖注入和IoC乍一看可能相当复杂,但它们