背景
近日设计师小姐姐创作能力爆棚,设计了一个狂拽酷炫的效果:星球环绕列表。如下图:
image
在拿着板砖去沟通,且看到对方40米长的大刀后,愉快地确认出页面的如下特性:
需要实现一个可围绕圆弧(图中星球)轨道旋转的列表。
圆形列表在只有一个item时,显示在轨道最右侧。
圆形列表下拉极限是第一个item在轨道最右侧。
圆形列表上拉极限是最后一个item在轨道最右侧。
圆形列表中的任一item均可设置到轨道最右侧。
item数量不会很多。
轨道为圆形右侧的少半段弧,轨道圆心及半径会给出。
一个半圆可以显示9个item。
在网络上遍寻轮子无果的情况下,最终决定自定义了这个CircleListView。
分析
首先,遇到这样的要求,内心会产生胆怯,此时需要为自己打气:
我们遇到什么困难也不要怕,微笑着面对它!消除恐惧的最好办法就是面对恐惧!坚持,才是胜利。加油!奥利给!
image
------------------------------------------跑偏了,言归正传------------------------------------------
最初,计划重写RecyclerView或ListView来实现上述要求。后来发现,系统自带的列表控件,难以计算每个item的坐标(系统列表控件必按照横向或竖向排列item,而圆弧列表不分横竖向,因为圆弧中两点之间可以指向任何方向),如下图就无法分辨两个item之间是横向关系还是竖向关系:
image
故重写系统列表不可行。捷径不可行,那就重写ViewGroup,自己计算并显示其中子View的位置,来实现需要的效果。
那么,每个item的位置怎么计算呢?我们来整理一下我们已知的位置相关的信息:圆弧的圆心位置及半径可以确认,为了兼容性适配,圆心及半径我们按照屏幕百分比进行转化:
圆心y轴坐标:控件高度*0.45
圆心x轴坐标:-控件宽度*0.25
圆的半径:控件宽度*0.9