我尝试像这个应用程序一样做圆圈菜单。
在“扩展”模式下,我绘制如下组件:
<RelativeLayout android:id="@+id/bigCircle">
<!--color full borders-->
<my.custom.component android:id="@+id/middleCircle">
<!--circle for buttons-->
<RelativeLayout android:id="@+id/smallCircle">
<!--minus button-->
</RelativeLayout>
</my.custom.component>
</RelativeLayout>
在my.custom.component
的onDraw方法中,我使用带有android.graphics.Path
的{{1}}和一些数学来划分8个部分的圆圈。
在视觉上我完全如截图所示。但是当我按下圆圈的一部分时,我需要用另一种颜色重新绘制这个部分,以向用户显示正在发生的事情。
我可以通过android.graphics.Paint
重新绘制部分画布中的部分画布切割掉另一部分画布。
换句话说,我知道在onDraw方法中我应该做什么重绘画布,我知道我可以从Photoshop中绘制的drawables中显示一些位图并且有一些“多屏幕故障”,我知道如何确定用户按下的部分。但我不知道如何选择画布的一部分并重新绘制它。
答案 0 :(得分:20)
Catch的开发者。如果我理解你的问题,你就无法理解如何在圆形菜单的某个部分专门绘制高亮/选择指示器。
虽然有很多不同的方法可以实现它,但你倾向于(使用android.graphics.Path
)是我们如何做到的。在我们的捕获按钮的视图层次结构中,有一个元素用作画布,在该画布上绘制选择突出显示颜色(如果 是活动选择)。
如果您的布局中有类似的自定义View
,则可以像这样复制此行为。首先,您需要Path
来定义特定圆弧段的选择。使用Path.addArc(RectF, float, float)
,我们可以获得所需的披萨片形路径:
private Path getPathForSegment(float startAngle, float sweep) {
Point center = new Point(getWidth() / 2, getHeight() / 2);
RectF rect = new RectF(0f, 0f, getWidth(), getHeight());
Path selection = new Path();
selection.addArc(rect, startAngle, sweep);
selection.lineTo(center.x, center.y);
selection.close();
return selection;
}
上面的getWidth()
和getHeight()
用于封闭的自定义视图对象,因此它们定义了包含绘制选区的圆的边界框。
然后,在您的自定义视图onDraw(Canvas)
中,如果您的代码已确定应为某个细分受众群提取选择:
@Override
protected void onDraw(Canvas canvas) {
// Assume one has the rest of these simple helper functions defined
if (shouldDrawSelection()) {
float startAngle = getStartAngleOfSelectedSegment();
float sweep = getSweepAngle();
Paint paint = getPaintStyleForSelectedSegment();
Path path = getPathForSegment(startAngle, sweep);
canvas.drawPath(path, paint);
}
// ...
super.onDraw(canvas);
}
在代码的其他跟踪触摸的区域中,只需在自定义视图上调用invalidate()
,以便根据输入或状态的变化重绘(或不重绘)选择路径。
请记住,最好避免new
onDraw()
中的Path
对象,因此大多数这些构建基块(Paint
s,{{1}}等都可以提前构建(或一次,在第一次出现时)并重复使用。
希望这接近你的要求!