用Canvas在Android上绘制半圆形

4

有人能帮我使用canvas画出下面图片的半圆形,还有如何检测绘制对象的碰撞吗?

Drawing Object

我尝试使用XML绘制它,但不知道如何检测它的碰撞。 我只想检测黑色部分的碰撞,而不是整个圆形。 谢谢。

2个回答

9

我刚刚完成了类似的事情,使用自定义视图:

class SemiCircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint: Paint = Paint()
    private var rectangle: RectF? = null
    private var margin: Float

    init {
        paint.isAntiAlias = true
        paint.color = ContextCompat.getColor(context, R.color.colorAquamarine)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 5.dpToPx()
        margin = 3.dpToPx() // margin should be >= strokeWidth / 2 (otherwise the arc is cut)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (rectangle == null) {
            rectangle = RectF(0f + margin, 0f + margin, width.toFloat() - margin, height.toFloat() - margin)
        }
        canvas.drawArc(rectangle!!, 90f, 180f, false, paint)
    }

}

将其添加到XML布局中,如下所示:
<com.example.view.SemiCircleView
    android:layout_width="120dp"
    android:layout_height="120dp"/>

那就是结果:

Android semi circle canvas setArc


在我的情况下,我希望通过编程方式控制绘制的圆的百分比,因此我添加了一个名为setArcProportion的方法来控制它:
class SemiCircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val mainPaint: Paint = Paint()
    private val backgroundPaint: Paint = Paint()
    private var rectangle: RectF? = null
    private var margin: Float
    private var arcProportion: Float = 0f

    init {
        mainPaint.isAntiAlias = true
        mainPaint.color = ContextCompat.getColor(context, R.color.colorLutea)
        mainPaint.style = Paint.Style.STROKE
        mainPaint.strokeWidth = 5.dpToPx()
        backgroundPaint.isAntiAlias = true
        backgroundPaint.color = ContextCompat.getColor(context, R.color.black_08)
        backgroundPaint.style = Paint.Style.STROKE
        backgroundPaint.strokeWidth = 5.dpToPx()
        margin = 3.dpToPx() // margin should be >= strokeWidth / 2 (otherwise the arc is cut)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (rectangle == null) {
            rectangle = RectF(0f + margin, 0f + margin, width.toFloat() - margin, height.toFloat() - margin)
        }
        canvas.drawArc(rectangle!!, -90f, arcProportion * 360, false, mainPaint)
        // This 2nd arc completes the circle. Remove it if you don't want it
        canvas.drawArc(rectangle!!, -90f + arcProportion * 360, (1 - arcProportion) * 360, false, backgroundPaint)
    }

    /**
     * @param arcProportion The proportion of the semi circle arc, from 0 to 1. Setting 0 makes the arc invisible, and 1
     * makes a whole circle.
     */
    fun setArcProportion(arcProportion: Float) {
        this.arcProportion = arcProportion
        invalidate()
    }

}

所以,如果我执行 semiCircleView.setArcProportion(0.62f) ,我会得到:

Android semi circle canvas setArc

奖励 - 要使弧形图随动画增长,请修改setArcProportion如下:

private const val ANIMATION_BASE_DURATION_MS: Long = 500 // milliseconds

fun setArcProportion(arcProportion: Float) {
    ValueAnimator.ofFloat(0f, arcProportion).apply {
        interpolator = DecelerateInterpolator()
        // The animation duration is longer for a larger arc
        duration = ANIMATION_BASE_DURATION_MS + (arcProportion * ANIMATION_BASE_DURATION_MS).toLong()
        addUpdateListener { animator ->
            this@SemiCircleView.arcProportion = animator.animatedValue as Float
            this@SemiCircleView.invalidate()
        }
        start()
    }
}

-1
  1. 在你的onDraw方法中画一个圆。

    canvas.drawCircle(x, y, 10, paint);

  2. 现在用你的背景颜色画一个矩形

    Paint fillBackgroundPaint = new Paint();
    fillBackgroundPaint.setAntiAlias(true);
    fillBackgroundPaint.setStyle(Paint.Style.FILL);
    canvas.drawRect(x,y+10,x+10,y-10);
    

这应该能够达到目的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接