简体   繁体   English

Android-细分Arc以使用菜单

[英]Android - Subdivide Arc for Menu usage

I would like to create a custom menu in android, which should look like the following picture. 我想在android中创建一个自定义菜单,该菜单应如下图所示。

Picture of the menu 菜单图片 在此处输入图片说明

I've already achieved to create the main part of the menu excluding the menu points. 我已经实现了创建菜单的主要部分(不包括菜单点)的工作。 So it looks like the following picture. 因此,它看起来像下面的图片。

Current state of the menu 菜单的当前状态 在此处输入图片说明

This Menu is a CustomView and I drew these arcs as RectF with the canvas.drawArc Method. 此菜单是一个CustomView,我使用canvas.drawArc方法将这些弧绘制为RectF。 So I think it's quite obvious, what I'd like to achieve. 因此,我想达到的目标很明显。 I want to subdivide the Arc into evenly sized smaller arcs, or add new ones (which are exactly on the other one). 我想将弧细分为大小均匀的较小弧,或添加新弧(恰好在另一弧上)。 I've tried to simply set the bounds of the these arcs to 1/3 of the bigger one, however, I can't achieve this result this way. 我试图简单地将这些弧的边界设置为较大弧的1/3,但是,我无法以这种方式实现此结果。

Does anyone know a method to do this, or do I completely change my approach? 有人知道这样做的方法吗,还是我完全改变了我的方法?

Ok. 好。 After some research, experimenting and simple math I've come up with the following code. 经过一番研究,实验和简单的数学运算,我得出了以下代码。

 private void drawMenu(Canvas canvas, RectF arcBoundaries, int arcAngle, int sweep, Paint arcPaint, MenuPosition position, double scaleValue, int strokeWidth) {

        int countAllMenuItems = getMenuCount(position);
        int newAngle = arcAngle;
        int counter = 0;

        for (MenuItemView menuItem : menuItems) {
            if (menuItem.getPosition().toLowerCase().equals(position.toString().toLowerCase())) {
                canvas.drawArc(arcBoundaries, newAngle, sweep / countAllMenuItems, false, arcPaint);
                newAngle += sweep / countAllMenuItems;
                if (counter != countAllMenuItems - 1) {
                    calculateLines(arcBoundaries, newAngle, strokeWidth);
                }
                counter++;
            }
        }

    }
}

private void calculateLines(RectF arcBoundaries, int angle, int strokeWidth) {
    int realAngle = angle % 360;
    float xRadius = arcBoundaries.width()/2;
    float yRadius = arcBoundaries.height()/2;

    double x = arcBoundaries.centerX() + (xRadius-(strokeWidth/2))*Math.cos(realAngle * Math.PI / 180);
    double y = arcBoundaries.centerY() + (yRadius-(strokeWidth/2))*Math.sin(realAngle * Math.PI / 180);
    double xEnd = arcBoundaries.centerX() + (xRadius+(strokeWidth/2))*Math.cos(realAngle * Math.PI / 180);
    double yEnd = arcBoundaries.centerY() + (yRadius+(strokeWidth/2))*Math.sin(realAngle * Math.PI / 180);


    lineList.put(new Point((int) x, (int) y), new Point((int) xEnd, (int) yEnd));
}

It is quite simple actually. 实际上,这很简单。 With the count of all MenuItems and the sweep angle, I calculate the angle of each line. 利用所有MenuItem的计数和扫掠角度,我计算出每条线的角度。 Then I use the angle functions to calculate the x and y start and end values. 然后,我使用角度函数来计算x和y的开始和结束值。

So I use the formulae: 所以我使用公式:

x (adjacent side) = centerX (adjust to coordinate system) + hypotenuse*cos(angle) x(相邻边)= centerX(调整坐标系)+斜边* cos(角度)

y (opposite side) = centerY (adjust to coordinate system) + hypotenuse*sin(angle) y(相对侧)= centerY(调整坐标系)+斜边* sin(角度)

It's important to mention that the angle in the angle functions have to be in radian measure. 重要的是要提到角度函数中的角度必须为弧度。 Also, I had to subtract/add have of the stroke because I used stroke style to draw these arcs, meaning that the radius goes to the center of the stroke. 另外,我必须减去/增加笔划的笔触数,因为我使用笔划样式绘制了这些弧线,这意味着半径位于笔划的中心。

I put these values in a list and draw them after I've drawn everything else, so they are above everything else. 我将这些值放在列表中,并在绘制完所有其他内容之后绘制它们,因此它们位于其他所有内容之上。

I hope I was able to help everyone, who stumbles over the same problem. 我希望我能够为遇到相同问题的每个人提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM