重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
首先来看看我们模仿的效果图,相信对于使用过QQ的人来说都不陌生,效果图如下:
成都创新互联公司-专业网站定制、快速模板网站建设、高性价比大荔网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式大荔网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖大荔地区。费用合理售后完善,十载实体公司更值得信赖。在以前的一个项目中,需要实现类似QQ讨论组头像的控件,只是头像数量和布局有一小点不一样:一是最头像数是4个,二是头像数是2个时的布局是横着排的。其实当时GitHub上就有类似的开源控件,只是那个控件在每一次绘制View的时候都会新创建一些Bitmap对象,这肯定是不可取的,而且那个控件头像输入的是Bitmap对象,不满足需求。所以只能自己实现一个了。实现的时候也没有过多的考虑,传入头像Drawable对象,根据数量排列显示就算完成了,而且传入的图像还必需是圆形的,限制很大,根本不具备通用性。因此要实现和QQ讨论组头像一样的又具备一定通用性的控件,还得重新设计、实现。
下面就让我们开始实现吧。
布局
首先需要解决的是头像的布局,在头像数量分别为1至5的情况下,定义头像的布局排列方式,并计算出图像的大小和位置。先把布局图画出来再说:
其中黑色正方形就是View的显示区,蓝色圆形就是头像了。已知的条件是View大小,姑且设为 D 吧,还有头像的数量 n ,求蓝色圆的半径 r 及圆心位置。这不就是一道几何题吗?翻开初中的数学课本——勾三股四弦五……好像不够用啊……
辅助线画了又画,头皮挠了又挠,α,θ,OMG......sin,cos,sh*t......终于算出了 r 与 D 和 n 的关系:
其实 n=3 的时候半径和 n=4 的时候是一样的,但是考虑到 n=3,5 时在Y轴上还有一个偏移量 dy ,而且 r 和 dy 在 n=3,5 时是有通式的,所以就合在一起了。求偏移量 dy 的公式:
式中 R 就是布局图中红色大圆的半径。
有了公式,那么代码就好写了,计算每个头像的大小和位置的代码如下:
// 头像信息类,记录大小、位置等信息 private static class DrawableInfo { int mId = View.NO_ID; Drawable mDrawable; // 中心点位置 float mCenterX; float mCenterY; // 头像上缺口弧所在圆上的圆心位置,其实就是下一个相邻头像的中心点 float mGapCenterX; float mGapCenterY; boolean mHasGap; // 头像边界 final RectF mBounds = new RectF(); // 圆形蒙板路径,把头像弄成圆形 final Path mMaskPath = new Path(); }