Android圆角正方形加载框

效果图
在这里插入图片描述
RecProgressLayout.kt

package com.oplayer
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.TypedValue
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.cardview.widget.CardView
import com.oplayer.myapplication.R

class RecProgressLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
//) : RelativeLayout(context, attrs, defStyleAttr) {
) : CardView(context, attrs, defStyleAttr) {

    companion object {
        //起点位置
        const val LEFT_TOP = 0
        const val RIGHT_TOP = 1
        const val RIGHT_BOTTOM = 2
        const val LEFT_BOTTOM = 3

        //方向
        const val CLOCKWISE = 0
        const val ANTI_CLOCKWISE = 1
    }

    /**
     * 进度条宽度
     */
    var progressWidth = 0f

    /**
     * 进度条颜色
     */
    var progressColor = Color.BLUE

    /**
     * 进度条背景
     */
    var progressBgColor = Color.TRANSPARENT

    /**
     * 进度条开始点
     */
    var startPoint = LEFT_TOP

    /**
     * 进度条进度方向
     */
    var orientation = CLOCKWISE

    /**
     * 文字颜色
     */
    var textColor = Color.BLACK

    /**
     * 文字大小
     */
    var textSize = 0f

    /**
     * 当前进度
     */
    var currentProgress = 0

    private var progressBgPaint: Paint
    private var progressPaint: Paint
    var textView: TextView? = null
//    var layoutParams: LayoutParams

    init {
        val a = context.obtainStyledAttributes(attrs, R.styleable.RecProgressLayout)
        progressWidth = a.getDimension(R.styleable.RecProgressLayout_rpl_progress_width, 1f)
        progressColor = a.getColor(R.styleable.RecProgressLayout_rpl_progress_color, Color.GREEN)
        progressBgColor =
            a.getColor(R.styleable.RecProgressLayout_rpl_progress_bg_color, Color.TRANSPARENT)
        startPoint = a.getInteger(R.styleable.RecProgressLayout_rpl_start_point, LEFT_TOP)
        orientation = a.getInteger(R.styleable.RecProgressLayout_rpl_orientation, CLOCKWISE)
        textColor = a.getColor(R.styleable.RecProgressLayout_rpl_text_color, Color.BLACK)
        textSize = a.getDimension(R.styleable.RecProgressLayout_rpl_text_size, 0f)
        currentProgress = a.getInteger(R.styleable.RecProgressLayout_rpl_current_progress, 0)
        a.recycle()

        progressBgPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        progressBgPaint.color = progressBgColor
        progressBgPaint.strokeWidth = progressWidth
        progressBgPaint.style = Paint.Style.STROKE

        progressBgPaint.strokeCap = Paint.Cap.ROUND

        progressPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        progressPaint.strokeCap = Paint.Cap.ROUND
        progressPaint.color = progressColor
        progressPaint.strokeWidth = 50f
        progressPaint.style = Paint.Style.STROKE
        progressPaint.strokeJoin = Paint.Join.ROUND

        if (textSize != 0f) {
            textView = TextView(context)
            textView?.setTextColor(textColor)
            textView?.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
        }

//        layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)

        setWillNotDraw(false)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
//        drawProgressBg(canvas)
        drawProgress(canvas)
        if (textView != null)
            drawText()
    }

    fun setProgress(progress: Int) {
        currentProgress = progress
        invalidate()
    }

    /**
     * 绘制进度条背景
     * @param canvas Canvas?
     */
    private fun drawProgressBg(canvas: Canvas?) {
        if (orientation == CLOCKWISE) {
            drawTop(canvas, progressBgPaint, width.toFloat())
            drawRight(canvas, progressBgPaint, height.toFloat())
            drawBottom(canvas, progressBgPaint, 0f)
            drawLeft(canvas, progressBgPaint, 0f)
        } else {
            drawTop(canvas, progressBgPaint, 0f)
            drawRight(canvas, progressBgPaint, 0f)
            drawBottom(canvas, progressBgPaint, width.toFloat())
            drawLeft(canvas, progressBgPaint, height.toFloat())
        }
    }

    /**
     * 绘制进度条
     * @param canvas Canvas?
     */
    private fun drawProgress(canvas: Canvas?) {
        val totalWidth = 2 * (width + height) - 4 * progressWidth
        val progress = totalWidth * (currentProgress / 100.0f)
        when (startPoint) {
            LEFT_TOP -> {
                drawAtLeftTop(canvas, totalWidth, progress)
            }
//            LEFT_BOTTOM -> {
//                drawAtLeftBottom(canvas, totalWidth, progress)
//            }
//            RIGHT_TOP -> {
//                drawAtRightTop(canvas, totalWidth, progress)
//            }
//            RIGHT_BOTTOM -> {
//                drawAtRightBottom(canvas, totalWidth, progress)
//            }
        }
    }

    @SuppressLint("NewApi")
    private fun drawText() {
        removeView(textView)
        val content = "$currentProgress%"
        textView?.text = content
//        layoutParams.addRule(CENTER_IN_PARENT)
//        textView?.layoutParams = layoutParams
        addView(textView)
    }

    /**
     * 绘制上方边进度条
     * @param canvas Canvas?
     */
    private fun drawTop(canvas: Canvas?, paint: Paint, width: Float) {
        if (orientation == CLOCKWISE) {
            canvas?.drawLine(
                progressWidth,
                progressWidth / 2.0f,
                width,
                progressWidth / 2.0f,
                paint
            )
        } else {
            canvas?.drawLine(
                this.width - progressWidth,
                progressWidth / 2.0f,
                width,
                progressWidth / 2.0f,
                paint
            )
        }
    }

    /**
     * 绘制右边进度条
     * @param canvas Canvas?
     */
    private fun drawRight(canvas: Canvas?, paint: Paint, height: Float) {
        if (orientation == CLOCKWISE) {
//            val paint = Paint().apply {
//                style = Paint.Style.STROKE
//                strokeWidth = 10f
//                color = Color.BLACK
//                strokeCap = Paint.Cap.ROUND
//            }



            canvas?.drawLine(
                width.toFloat() - progressWidth / 2.0f,
                progressWidth,
                width.toFloat() - progressWidth / 2.0f,
                height,
                paint
            )

//            var w = 500f
//            var h = 500f
//            var centerX = w/2f
//            var centerY = h/2f
//            var  start = PointF()
//            var  end =PointF()
//            var  control =PointF()
//            // 初始化数据点和控制点的位置
//            start.x = width.toFloat() - progressWidth / 2.0f
//            start.y = progressWidth
//            end.x =width.toFloat() - progressWidth / 2.0f
//            end.y = height
//            control.x = 0f
//            control.y = 700f
//            Slog.d("输出progressWidth=$progressWidth++$height")
//            // 绘制贝塞尔曲线f
//            var path = Path()
//            path.moveTo(start.x,start.y);
//            path.quadTo(control.x,control.y,end.x,end.y)
//            canvas?.drawPath(path, paint)

//            var mRectF = RectF(10f, 10f, 600f, 600f)
//            path.arcTo(mRectF, 0f, 90f)
//            canvas!!.drawPath(path, paint)

//            val p = 6f
//            paint.color = UIUtils.getColor(R.color.yellow_heart_color)
//            val rectF = RectF(p, p, width.toFloat() - p, height.toFloat() - p)
//
//            canvas?.drawRoundRect(rectF, 80f, 80f, paint)  // 绘制方形圆角边框

//            var progress2 = 60
//            var maxProgress2 = 100
//            var cornerRadius = 6f
//            var progressWidth = 0f
//            var backgroundColor2 = Color.GRAY
//            var progressColor = Color.BLUE
//            val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
//
//            val rectF2 = RectF(0f, 0f, width.toFloat(), height.toFloat())
//            canvas?.drawRoundRect(rectF2, cornerRadius, cornerRadius, backgroundPaint)
//
//            val progressWidth2 = progress2 * (width - 2 * cornerRadius) / maxProgress2.toFloat()
//            val progressRectF = RectF(cornerRadius, cornerRadius, cornerRadius + progressWidth2, height - cornerRadius)
//            canvas?.drawRoundRect(progressRectF, cornerRadius, cornerRadius, progressPaint)

            // 计算进度条的位置和宽度
//            val progressRect = RectF(
//                borderWidth / 2,       // left
//                height - progressHeight - borderWidth / 2,       // top
//                progress * (width - borderWidth) - borderWidth / 2, // right
//                height - borderWidth / 2   // bottom
//            )

            // 画进度条矩形
//            progressPaint.color = Color.RED
//            canvas?.drawRect(rectF, progressPaint)

        } else {
            canvas?.drawLine(
                width - progressWidth / 2.0f,
                this.height - progressWidth,
                width - progressWidth / 2.0f,
                height,
                paint
            )
        }
    }

    /**
     * 绘制下方进度条
     * @param canvas Canvas?
     */
    private fun drawBottom(canvas: Canvas?, paint: Paint, width: Float) {
        if (orientation == CLOCKWISE) {
            canvas?.drawLine(
                this.width - progressWidth,
                height.toFloat() - progressWidth / 2.0f,
                width,
                height.toFloat() - progressWidth / 2.0f,
                paint
            )
        } else {
            canvas?.drawLine(
                progressWidth,
                height - progressWidth / 2.0f,
                width,
                height - progressWidth / 2.0f,
                paint
            )
        }
    }

    /**
     * 绘制左边进度条
     * @param canvas Canvas?
     */
    private fun drawLeft(canvas: Canvas?, paint: Paint, height: Float) {
        if (orientation == CLOCKWISE) {
            canvas?.drawLine(
                progressWidth / 2.0f,
                this.height - progressWidth,
                progressWidth / 2.0f,
                height,
                paint
            )
        } else {
            canvas?.drawLine(
                progressWidth / 2.0f,
                progressWidth,
                progressWidth / 2.0f,
                height,
                paint
            )
        }
    }

    /**
     * 绘制起点在左上
     * @param canvas Canvas?
     * @param totalWidth Float
     * @param progress Float
     */
    private fun drawAtLeftTop(canvas: Canvas?, totalWidth: Float, progress: Float) {
        if (orientation == CLOCKWISE) {
            if (progress >= width - progressWidth) {
                drawTop(canvas, progressPaint, width.toFloat())
                if (currentProgress >= 50) {
                    drawRight(canvas, progressPaint, height.toFloat())
                    if (progress >= width * 2 + height - 3 * progressWidth) {
                        drawBottom(canvas, progressPaint, 0f)
                        if (currentProgress == 100) {
                            drawLeft(canvas, progressPaint, 0f)
                        } else {
                            drawLeft(canvas, progressPaint, totalWidth - progress)
                        }
                    } else {
                        drawBottom(
                            canvas,
                            progressPaint,
                            2 * width + height - 3 * progressWidth - progress
                        )
                    }
                } else {
                    drawRight(
                        canvas,
                        progressPaint,
                        progress - width + 2 * progressWidth
                    )
                }
            } else {
                drawTop(canvas, progressPaint, progressWidth + progress)
            }
        } else {
            if (progress >= height - progressWidth) {
                drawLeft(canvas, progressPaint, height.toFloat())
                if (currentProgress >= 50) {
                    drawBottom(canvas, progressPaint, height.toFloat())
                    if (progress >= height * 2 + width - 3 * progressWidth) {
                        drawRight(canvas, progressPaint, 0f)
                        if (currentProgress == 100) {
                            drawTop(canvas, progressPaint, 0f)
                        } else {
                            drawTop(canvas, progressPaint, width - (totalWidth - progress))
                        }
                    } else {
                        drawRight(
                            canvas,
                            progressPaint,
                            2 * height + width - (progress + 3 * progressWidth)
                        )
                    }
                } else {
                    drawBottom(
                        canvas,
                        progressPaint,
                        progress + 2 * progressWidth - height
                    )
                }
            } else {
                drawLeft(canvas, progressPaint, progressWidth + progress)
            }
        }
    }

    /**
     * 绘制起点在左下
     * @param canvas Canvas?
     * @param totalWidth Float
     * @param progress Float
     */
    private fun drawAtLeftBottom(canvas: Canvas?, totalWidth: Float, progress: Float) {
        if (orientation == CLOCKWISE) {
            if (progress >= height - progressWidth) {
                drawLeft(canvas, progressPaint, 0f)
                if (currentProgress >= 50) {
                    drawTop(canvas, progressPaint, width.toFloat())
                    if (progress >= height * 2 + width - 3 * progressWidth) {
                        drawRight(canvas, progressPaint, height.toFloat())
                        if (currentProgress == 100) {
                            drawBottom(canvas, progressPaint, 0f)
                        } else {
                            drawBottom(canvas, progressPaint, totalWidth - progress)
                        }
                    } else {
                        drawRight(
                            canvas,
                            progressPaint,
                            progress - 3 * progressWidth - height - width
                        )
                    }
                } else {
                    drawTop(
                        canvas,
                        progressPaint,
                        progress - height + 2 * progressWidth
                    )
                }
            } else {
                drawLeft(canvas, progressPaint, height - progress)
            }
        } else {
            if (progress >= width - progressWidth) {
                drawBottom(canvas, progressPaint, width.toFloat())
                if (currentProgress >= 50) {
                    drawRight(canvas, progressPaint, 0f)
                    if (progress >= width * 2 + height - 3 * progressWidth) {
                        drawTop(canvas, progressPaint, 0f)
                        if (currentProgress == 100) {
                            drawLeft(canvas, progressPaint, height.toFloat())
                        } else {
                            drawLeft(
                                canvas,
                                progressPaint,
                                height - (totalWidth - progress)
                            )
                        }
                    } else {
                        drawTop(
                            canvas,
                            progressPaint,
                            2 * width + height - (progress + 3 * progressWidth)
                        )
                    }
                } else {
                    drawRight(
                        canvas,
                        progressPaint,
                        height + width - (progress + 2 * progressWidth)
                    )
                }
            } else {
                drawBottom(canvas, progressPaint, progress)
            }
        }
    }

    /**
     * 绘制起点在右上
     * @param canvas Canvas?
     * @param totalWidth Float
     * @param progress Float
     */
    private fun drawAtRightTop(canvas: Canvas?, totalWidth: Float, progress: Float) {
        if (orientation == CLOCKWISE) {
            if (progress >= height - progressWidth) {
                drawRight(canvas, progressPaint, height.toFloat())
                if (currentProgress >= 50) {
                    drawBottom(canvas, progressPaint, 0f)
                    if (progress >= height * 2 + width - 3 * progressWidth) {
                        drawLeft(canvas, progressPaint, 0f)
                        if (currentProgress == 100) {
                            drawTop(canvas, progressPaint, width.toFloat())
                        } else {
                            drawTop(canvas, progressPaint, width - (totalWidth - progress))
                        }
                    } else {
                        drawLeft(
                            canvas,
                            progressPaint,
                            2 * height + width - 3 * progressWidth - progress
                        )
                    }
                } else {
                    drawBottom(
                        canvas,
                        progressPaint,
                        width + height - progress - 2 * progressWidth
                    )
                }
            } else {
                drawRight(canvas, progressPaint, progressWidth + progress)
            }
        } else {
            if (progress >= width - progressWidth) {
                drawTop(canvas, progressPaint, 0f)
                if (currentProgress >= 50) {
                    drawLeft(canvas, progressPaint, height.toFloat())
                    if (progress >= width * 2 + height - 3 * progressWidth) {
                        drawBottom(canvas, progressPaint, width.toFloat())
                        if (currentProgress == 100) {
                            drawRight(canvas, progressPaint, 0f)
                        } else {
                            drawRight(canvas, progressPaint, totalWidth - progress)
                        }
                    } else {
                        drawBottom(
                            canvas,
                            progressPaint,
                            progress + 3 * progressWidth - width - height
                        )
                    }
                } else {
                    drawLeft(
                        canvas,
                        progressPaint,
                        progress + 2 * progressWidth - width
                    )
                }
            } else {
                drawTop(canvas, progressPaint, width - progressWidth - progress)
            }
        }
    }

    /**
     * 绘制起点在左上
     * @param canvas Canvas?
     * @param totalWidth Float
     * @param progress Float
     */
    private fun drawAtRightBottom(canvas: Canvas?, totalWidth: Float, progress: Float) {
        if (orientation == CLOCKWISE) {
            if (progress >= width - progressWidth) {
                drawBottom(canvas, progressPaint, 0f)
                if (currentProgress >= 50) {
                    drawLeft(canvas, progressPaint, 0f)
                    if (progress >= width * 2 + height - 3 * progressWidth) {
                        drawTop(canvas, progressPaint, width.toFloat())
                        if (currentProgress == 100) {
                            drawRight(canvas, progressPaint, height.toFloat())
                        } else {
                            drawRight(canvas, progressPaint, totalWidth - progress)
                        }
                    } else {
                        drawTop(
                            canvas,
                            progressPaint,
                            3 * progressWidth + progress - width - height
                        )
                    }
                } else {
                    drawLeft(
                        canvas,
                        progressPaint,
                        width + height - progress - 2 * progressWidth
                    )
                }
            } else {
                drawBottom(canvas, progressPaint, width - progressWidth - progress)
            }
        } else {
            if (progress >= height - progressWidth) {
                drawRight(canvas, progressPaint, 0f)
                if (currentProgress >= 50) {
                    drawTop(canvas, progressPaint, 0f)
                    if (progress >= height * 2 + width - 3 * progressWidth) {
                        drawLeft(canvas, progressPaint, height.toFloat())
                        if (currentProgress == 100) {
                            drawBottom(canvas, progressPaint, width.toFloat())
                        } else {
                            drawBottom(canvas, progressPaint, width - (totalWidth - progress))
                        }
                    } else {
                        drawLeft(
                            canvas,
                            progressPaint,
                            progress + 3 * progressWidth - width - height
                        )
                    }
                } else {
                    drawTop(
                        canvas,
                        progressPaint,
                        height + width - progress - 2 * progressWidth
                    )
                }
            } else {
                drawRight(canvas, progressPaint, height - progress - progressWidth)
            }
        }
    }
}

atter.xml

    <declare-styleable name="RecProgressLayout">

        <attr name="rpl_progress_width" format="dimension" />
        <attr name="rpl_progress_color" format="color|reference" />
        <attr name="rpl_progress_bg_color" format="color|reference" />
        <attr name="rpl_start_point" format="enum">
            <enum name="left_top" value="0" />
            <enum name="right_top" value="1" />
            <enum name="right_bottom" value="2" />
            <enum name="left_bottom" value="3" />
        </attr>
        <attr name="rpl_orientation" format="enum">
            <enum name="clockwise" value="0" />
            <enum name="anti_clockwise" value="1" />
        </attr>
        <attr name="rpl_text_color" format="color|reference" />
        <attr name="rpl_text_size" format="dimension" />
        <attr name="rpl_current_progress" format="integer" />

    </declare-styleable>
    <com.oplayer.RecProgressLayout
        android:id="@+id/rec_layout2"
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:cardCornerRadius="30dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:rpl_current_progress="80"
        app:rpl_orientation="clockwise"
        app:rpl_progress_bg_color="@color/teal_200"
        app:rpl_progress_color="@color/teal_700"
        app:rpl_progress_width="8dp"
        app:rpl_start_point="left_top">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="10dp"
            android:layout_below="@+id/p"
            android:scaleType="centerCrop"
            android:src="@mipmap/clockface_addbg" />
    </com.oplayer.RecProgressLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信工院李平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值