效果
国际惯例,效果奉上
思路
- 首先确定的是所有的参数,三个画笔(画线,画图,画字)
- 确定画出的形状参数,几边形、几层图形(上图一共为4层显示)、最外圈的半径、每层图形的角度和半径就可以算出来了;
- 确定该如何画出点(也就是能力值)
- 最后绘制文字
- Tips: 好的封装可以实现自定义设置View的各种属性;
实现
-
确定参数
在构造函数中实现了三个方法,分别初始化相应的参数public class AibilitysView extends View { private Paint linePaint;//画线的笔 private Paint textPaint;//画文字的笔 private Object[] allAbility; private int n; //边的数量或者能力的个数 private float intervalCount;//间隔数量,把半径分为几段 private float R; //最外圈的半径 private float angle; //角度 private int viewHight;//控件的高度 private int viewWidth;//控件的宽度 private ArrayList<ArrayList<PointF>> pointArrayList;//存储多边形顶点数组的数组 private ArrayList<PointF> abilityPoints;//储存能力点的数组 public AibilitysView(Context context) { this(context, null); } public AibilitysView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public AibilitysView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initSize(); initPoints(); initPaint(); } *** }
-
initSize()
方法先初始化了相关SIze
参数(默认的参数为 10 个边,最外层的半径长度为100dp
)/** * 初始化固定数据Size * 设置了是几边型; * 设置了最外圈的半径 * 计算出每一边型的角度 * 获取屏幕方向 */ private void initSize() { if (allAbility == null) { n = 10;//十条辺 } else { n = allAbility.length; } R = dp2pxF(getContext(), 100); intervalCount = 4; //有四层 angle = (float) ((2 * Math.PI) / n); //2π是一周,除以n是算出平均每一个的角度是多少 /** * * 此方法默认获取的是整个手机的宽度和高度;无论如何调节控件或父控件的宽度都不可能实现,Size的改变 * * //拿到屏幕的宽高 int screenWidth = getResources().getDisplayMetrics().widthPixels; //控件设置为正方向 viewHight = screenWidth; viewWidth = screenWidth; */ }
-
initPoints()
方法初始化点的位置(通过计算算出点的位置)/** * 初始化点的位置 */ private void initPoints() { if (pointArrayList == null) { pointArrayList = new ArrayList<>(); } else { pointArrayList.clear(); } float x; float y; for (int i = 0; i < intervalCount; i++) { //创建一个存储点的数组 ArrayList<PointF> points = new ArrayList<>(); for (int j = 0; j < n; j++) { float r = R * ((float) (intervalCount - i) / intervalCount);//每一圈的半径按比例减少 //这里减去Math.PI /2 是为了让段变形逆时针旋转90度,所以后面的所有用到cos,sin的都要减 x = (float) (r * Math.cos(j * angle - Math.PI / 2)); y = (float) (r * Math.sin(j * angle - Math.PI / 2)); points
-