如何在半圆自定义视图上包装内容?

Posted

技术标签:

【中文标题】如何在半圆自定义视图上包装内容?【英文标题】:How to do wrap content on half circle custom view? 【发布时间】:2019-08-24 03:47:11 【问题描述】:

我正在 android 上制作半圆自定义视图。但是,我正在努力删除包装内容上不需要的底部空白。我认为是因为它是基于“一个完整的圆”计算绘制的。 我正在分享我的自定义视图实现,以及我如何从我的应用程序中调用它。 另请参阅此图像: Click here for the screenshot

注意:如果我改变 onMeasure 的大小,那么它会切掉上面的圆圈: Click here for the screenshot

class CircularProgressView(context: Context, attrs: AttributeSet) : View(context, attrs) 

    private var circle = RectF()
    private val paint = Paint()
    private var size = 0

    init 
        paint.isAntiAlias = true
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = strokeWidth.toFloat()
        paint.strokeCap = Paint.Cap.BUTT

        setupAttributes(attrs)
    

    private fun setupAttributes(attrs: AttributeSet?) 

        // TypedArray objects are shared and must be recycled.
        typedArray.recycle()
    

    override fun onDraw(canvas: Canvas) 
        super.onDraw(canvas)

        drawBackground(canvas)
    


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        size = Math.min(measuredWidth, measuredHeight)

        setMeasuredDimension(size, size)
    


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) 
        super.onSizeChanged(w, h, oldw, oldh)

        val centerX = w / 2
        val centerY = h / 2

        // Pick the minimum value so that it can fit the container. Radius is half size
        val radius = size / 2f

        // Create the background and progress circle, adding dialStrokeWidth in equation so that make sure the dial can fit container
        circle.top = (centerY - radius)
        circle.bottom = (centerY + radius)
        circle.left = (centerX - radius)
        circle.right = (centerX + radius)
    

    private fun drawBackground(canvas: Canvas) 
        paint.shader = null
        paint.color = backGroundColor
        canvas.drawArc(circle, startAngle, sweepAngle, false, paint)
    

我就是这样使用它的:

<com.enova.circular_progress.CircularProgressView
                    android:layout_
                    android:layout_
                    android:background="@color/white"
                    app:backgroundColor="@color/colorHint"
                    app:dialColor="@color/colorPrimary"
                    app:foregroundColorEnd="@color/colorPrimary"
                    app:foregroundColorStart="@color/colorPrimaryDark"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:percent="80">
                </com.enova.circular_progress.CircularProgressView>               

【问题讨论】:

【参考方案1】:

更改您的 onMeasure。您将测量的宽度和高度设置为相同的值。如果您只想显示一个上半圆,那么您需要将高度设置为宽度的一半。否则,它会认为视图是整个高度的圆。

【讨论】:

所以它不应该是一半,因为在查看您的屏幕截图后,您会低于中点(超过 180 度的弧度)。使用三角法计算出您在 0 以下的距离,并根据该值更改您的尺寸。但答案是你的 onMeasure 错了,需要调整。如果它不准确,你会得到空格

以上是关于如何在半圆自定义视图上包装内容?的主要内容,如果未能解决你的问题,请参考以下文章

自定义图像视图切割左右边缘半圆形

为自定义包装器视图添加示例视图到 PreviewProvider

iOS 7:自定义容器视图控制器和内容插入

如何实现一个自定义属性包装器,它将发布 SwiftUI 的更改以重新呈现它的视图

SwiftUI - 在视图中包装 Button,以创建自定义按钮

如何在 SwiftUI 视图中包装 UIBarButtonItem?