当前位置:   article > 正文

android开发自定义View(四)仿掌上英雄联盟能力值分析效果

android开发自定义View(四)仿掌上英雄联盟能力值分析效果

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布


原始图效果


这里写图片描述



模仿效果


PNG
这里写图片描述

GIF
这里写图片描述

流程


  1. 绘制中心线,用于计算外层多边形各点的坐标
  2. 绘制最外层多边形
  3. 分析原型图算出每个多边形之间的间距
  4. 绘制里三层多边形
  5. 绘制字体
  6. 根据进度值绘制等级进度


难点


关键在于坐标的计算(三角函数的运用,哈哈),与旋转角度的掌控。



绘制中心线


/**
     * 绘制中心线
     *
     * @param canvas
     */
    private void center(Canvas canvas) {
        //绘制七边形中心线
        canvas.save();//保存当前状态
        canvas.rotate(0, center, center);
        float startY = getPaddingTop() + 2 * str_rect.height();
        float endY = center;
        float du = (float) (360 / 7 + 0.5);
        for (int i = 0; i < 7; i++) {
            canvas.drawLine(center, startY, center, endY, center_paint);
            canvas.rotate(du, center, center);

        }
        canvas.restore();//恢复之前状态
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里写图片描述
先计算出圆心到A点的坐标,
在计算出旋转的角度(360/7),
然后旋转7次Canvas,绘制7条中心线。
为了加深显示效果,先绘制一个绿色背景作参考。
这里写图片描述

绘制最外层正七边形


这里写图片描述
各坐标点的计算主要用到了三角函数。

A点

x : 对应圆心center。
y :paddingTop+2个字体高度的距离

B点
这里写图片描述

x : A点的x坐标+EB

利用三角函数公式,BE=sin(AB的夹角)*OB

这里有个坑,Math.sin(x)里的x是弧度,而不是角度。

如果要计算角度则需要加上Math.sin(Math.toRadians(x))

center+ Math.sin(Math.toRadians(360/7)) *one_radius

y :A点的y坐标+AE

同理AE=OA-OE,OE=cos(AB的夹角)*OB

OE=cos(AB的夹角)*OB

Math.abs(Math.cos(Math.toRadians(360/7)) *one_radius

由于余弦有正负值,这里要取绝对值

AE=OA-OE

(getPaddingTop() +2*str_rect.height() +one_radius

  • Math.abs(Math.cos(Math.toRadians(360/7)) *one_radius))

C点
这里写图片描述
x :圆心X+FC
Math.sin(Math.toRadians(360/7+360/7/2)) *one_radius

y: 圆心Y+OF
(Math.cos(Math.toRadians(360/7+360/7/2)) *one_radius) +center

D点
这里写图片描述

x :圆心x+HD

center+ Math.sin(Math.toRadians(360/7/2)) *one_radius

y:圆心y+OH

Math.cos(Math.toRadians(360/7/2)) *one_radius) +center

右边点绘制完后,左边点自然就简单了,y位置一样,x位置只需要把相加改成相减即可。

这里写图片描述


绘制内三层正七边形


绘制完最外层七边形后,剩下来的就好办了,只需要计算出每个七边形的间距即可。
由原型图分析,每一个正七边形占半径的四分之一。

 /**
     * 绘制第二层多边形
     *
     * @param canvas
     */
    private void twoPolygons(Canvas canvas) {
        distance = one_radius / 4;
        Path path = new Path();
        path.moveTo(center, getPaddingTop() + 2 * str_rect.height() + distance);                           //起始点
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7)) * (one_radius - distance)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - distance))));
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7)) * (one_radius - distance)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - distance))));
        path.close();
        canvas.drawPath(path, two_paint);
    }

    /**
     * 绘制第三层多边形
     *
     * @param canvas
     */
    private void threePolygons(Canvas canvas) {
        distance = one_radius / 2;
        Path path = new Path();
        path.moveTo(center, getPaddingTop() + 2 * str_rect.height() + distance);                           //起始点
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7)) * (one_radius - distance)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - distance))));
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7)) * (one_radius - distance)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - distance))));

        path.close();
        canvas.drawPath(path, three_paint);
    }

    /**
     * 绘制最内层多边形
     *
     * @param canvas
     */
    private void fourPolygons(Canvas canvas) {
        distance = one_radius / 2 + one_radius / 4;
        Path path = new Path();
        path.moveTo(center, getPaddingTop() + 2 * str_rect.height() + distance);                           //起始点
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7)) * (one_radius - distance)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - distance))));
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - distance)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7)) * (one_radius - distance)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - distance))));

        path.close();
        canvas.drawPath(path, four_paint);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

去掉绿色背景后,显示的效果
这里写图片描述


绘制字体


根据最外层多边形各点坐标以及字体的长度高度 微调。


privateRectstr_rect;//字体矩形

String[]str= {"击杀","生存","助攻","物理","魔法","防御","金钱"};

 /**
     * 绘制字体
     *
     * @param canvas
     */
    private void PaintFout(Canvas canvas) {
        canvas.drawText(str[0], center - str_rect.width() / 2, (float) (getPaddingTop() + 1.5 * str_rect.height()), str_paint);
        canvas.drawText(str[1], (float) (center + Math.sin(Math.toRadians(360 / 7)) * one_radius + str_rect.height() / 2), (float) ((getPaddingTop() + 2 * str_rect.height() + one_radius - Math.abs(Math.cos(Math.toRadians(360 / 7)) * one_radius))), str_paint);
        canvas.drawText(str[2], (float) (center + Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * one_radius + str_rect.height() / 2), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * one_radius) + center + str_rect.height() / 2, str_paint);
        canvas.drawText(str[3], (float) (center + Math.sin(Math.toRadians(360 / 7 / 2)) * one_radius - str_rect.height() / 2 + str_rect.width() / 2), (float) ((Math.cos(Math.toRadians(360 / 7 / 2)) * one_radius) + center + str_rect.height()), str_paint);
        canvas.drawText(str[4], (float) (center - Math.sin(Math.toRadians(360 / 7 / 2)) * one_radius + str_rect.height() / 2 - str_rect.width() * 1.5), (float) ((Math.cos(Math.toRadians(360 / 7 / 2)) * one_radius) + center + str_rect.height()), str_paint);
        canvas.drawText(str[5], (float) (center - Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * one_radius - str_rect.height() / 2 - str_rect.width()), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * one_radius) + center + str_rect.height() / 2, str_paint);
        canvas.drawText(str[6], (float) (center - Math.sin(Math.toRadians(360 / 7)) * one_radius - str_rect.height() / 2 - str_rect.width()), (float) ((getPaddingTop() + 2 * str_rect.height() + one_radius - Math.abs(Math.cos(Math.toRadians(360 / 7)) * one_radius))), str_paint);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这里写图片描述


绘制各能力值进度


 /**
     * 绘制等级进度
     */
    private void PaintRank(Canvas canvas) {

        Path path = new Path();
        path.moveTo(center, getPaddingTop() + 2 * str_rect.height() + f1);                           //起始点
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7)) * (one_radius - f2)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - f2))));
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - f3)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - f3)) + center);
        path.lineTo((float) (center + Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - f4)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - f4)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 / 2)) * (one_radius - f5)), (float) (Math.cos(Math.toRadians(360 / 7 / 2)) * (one_radius - f5)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - f6)), (float) (Math.cos(Math.toRadians(360 / 7 + 360 / 7 / 2)) * (one_radius - f6)) + center);
        path.lineTo((float) (center - Math.sin(Math.toRadians(360 / 7)) * (one_radius - f7)), (float) (getPaddingTop() + 2 * str_rect.height() + (one_radius) - Math.abs(Math.cos(Math.toRadians(360 / 7)) * (one_radius - f7))));
        path.close();
        canvas.drawPath(path, mPaint);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这里写图片描述

感兴趣的同学可直接到github下载源码查看。
如果你觉得还不错,可以给个star,支持下,谢谢了!
https://github.com/jiangzehui/polygonsview

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/384752?site
推荐阅读
相关标签
  

闽ICP备14008679号