最新公告
  • 欢迎您光临AA分享网,一个高级程序员的学习、分享的分享平台!立即加入我们
  • android开发自定义View(四)仿掌上英雄联盟能力值分析效果

    原文出处:http://blog.csdn.net/as7210636/article/details/52692102 

    原始图效果

    20160928170502130.png

    模仿效果

    png

    20160928170615521.png

    gif

    20160928170643287.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();//恢复之前状态
        }

    20160928171144184.jpg

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

    20160928171243764.jpg

    绘制最外层正七边形

    20160928171403931.jpg

    各坐标点的计算主要用到了三角函数。

    A点

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

    B点 

    20160928171744631.jpg

    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点 

    20160928172126809.jpg

    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点 

    20160928172303513.png

    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位置只需要把相加改成相减即可。

    20160928172455359.jpg

    绘制内三层正七边形

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

    /**
         * 绘制第二层多边形
         *
         * @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);
        }

    去掉绿色背景后,显示的效果 

    20160928172747108.jpg

    绘制字体

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

    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);
        }

    20160928172929678.jpg

    绘制各能力值进度

    /**
         * 绘制等级进度
         */
        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);
        }

    20160928173128173.jpg

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

    AA分享网一个高级程序员的学习、分享的IT资源分享平台
    AA分享网-企业网站源码-PHP源码-网站模板-视频教程-IT技术教程 » android开发自定义View(四)仿掌上英雄联盟能力值分析效果
    • 262会员总数(位)
    • 5946资源总数(个)
    • 4本周发布(个)
    • 0 今日发布(个)
    • 570稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情