优化圆形progressbar
This commit is contained in:
parent
e1d1dbb2b0
commit
c4855e93cf
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.ama.core.common.widget.DragLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.ama.core.common.widget.DragLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingVertical="7dp"
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
<!--<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<ProgressBar
|
||||
|
|
@ -56,7 +56,19 @@
|
|||
android:layout_gravity="center"
|
||||
android:paddingVertical="7dp"
|
||||
/>
|
||||
</FrameLayout>
|
||||
</FrameLayout>-->
|
||||
<com.ama.core.architecture.widget.CircleProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
app:progressColor="@color/progress_green"
|
||||
app:backgroundColor="@color/progress_background"
|
||||
app:progressWidth="2dp"
|
||||
app:centerIcon="@mipmap/home_envelope"
|
||||
app:currentProgress="35"
|
||||
app:maxProgress="100"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.ama.core.common.widget.DragLayout>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,197 @@
|
|||
package com.ama.core.architecture.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.ama.core.architecture.R
|
||||
import com.ama.core.common.util.dp
|
||||
|
||||
class CircleProgressBar @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : View(context, attrs, defStyleAttr) {
|
||||
|
||||
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
style = Paint.Style.FILL
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
}
|
||||
|
||||
private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
style = Paint.Style.STROKE
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
}
|
||||
|
||||
|
||||
|
||||
private var progressWidth = 0f
|
||||
private var progressColor = 0
|
||||
private var backgroundColor = 0
|
||||
private var centerIcon: Bitmap? = null
|
||||
|
||||
private var maxProgress = 100
|
||||
private var currentProgress = 0
|
||||
private var startAngle = -90f
|
||||
|
||||
private val rectF = RectF()
|
||||
private var viewSize = 0
|
||||
|
||||
init {
|
||||
initAttributes(attrs, defStyleAttr)
|
||||
}
|
||||
|
||||
private fun initAttributes(attrs: AttributeSet?, defStyleAttr: Int) {
|
||||
val typedArray = context.obtainStyledAttributes(
|
||||
attrs, R.styleable.CircleProgressBar, defStyleAttr, 0
|
||||
)
|
||||
|
||||
try {
|
||||
// 获取自定义属性
|
||||
progressColor = typedArray.getColor(
|
||||
R.styleable.CircleProgressBar_progressColor,
|
||||
ContextCompat.getColor(context, R.color.progress_green)
|
||||
)
|
||||
|
||||
backgroundColor = typedArray.getColor(
|
||||
R.styleable.CircleProgressBar_backgroundColor,
|
||||
ContextCompat.getColor(context, R.color.progress_background)
|
||||
)
|
||||
|
||||
progressWidth = typedArray.getDimension(
|
||||
R.styleable.CircleProgressBar_progressWidth,
|
||||
dpToPx(2f)
|
||||
)
|
||||
|
||||
val iconRes = typedArray.getResourceId(R.styleable.CircleProgressBar_centerIcon, 0)
|
||||
if (iconRes != 0) {
|
||||
setCenterIcon(iconRes)
|
||||
}
|
||||
|
||||
maxProgress = typedArray.getInt(R.styleable.CircleProgressBar_maxProgress, 100)
|
||||
currentProgress = typedArray.getInt(R.styleable.CircleProgressBar_currentProgress, 0)
|
||||
startAngle = typedArray.getInt(R.styleable.CircleProgressBar_startAngle, -90).toFloat()
|
||||
|
||||
} finally {
|
||||
typedArray.recycle()
|
||||
}
|
||||
|
||||
setupPaints()
|
||||
}
|
||||
|
||||
private fun setupPaints() {
|
||||
backgroundPaint.color = backgroundColor
|
||||
backgroundPaint.strokeWidth = progressWidth
|
||||
|
||||
progressPaint.color = progressColor
|
||||
progressPaint.strokeWidth = progressWidth
|
||||
|
||||
// 设置半透明效果,模仿图片中的绿色弧线
|
||||
progressPaint.alpha = 180
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
val width = MeasureSpec.getSize(widthMeasureSpec)
|
||||
val height = MeasureSpec.getSize(heightMeasureSpec)
|
||||
viewSize = minOf(width, height)
|
||||
setMeasuredDimension(viewSize, viewSize)
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
|
||||
val padding = progressWidth / 2
|
||||
rectF.set(
|
||||
padding,
|
||||
padding,
|
||||
w - padding,
|
||||
h - padding
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
|
||||
// 绘制背景圆环
|
||||
canvas.drawArc(rectF, 0f, 360f, false, backgroundPaint)
|
||||
|
||||
// 绘制进度弧线
|
||||
if (currentProgress > 0) {
|
||||
val sweepAngle = (currentProgress.toFloat() / maxProgress) * 360f
|
||||
canvas.drawArc(rectF, startAngle, sweepAngle, false, progressPaint)
|
||||
}
|
||||
|
||||
// 绘制中心图标
|
||||
centerIcon?.let { icon ->
|
||||
drawCenterIcon(canvas, icon)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun drawCenterIcon(canvas: Canvas, icon: Bitmap) {
|
||||
val centerX = width / 2f
|
||||
val centerY = height / 2f
|
||||
val iconWidth = icon.width.toFloat()
|
||||
val iconHeight = icon.height.toFloat()
|
||||
val iconBorderMargin = 12.dp
|
||||
|
||||
|
||||
val scale: Float = if (iconWidth > iconHeight) {
|
||||
(width - iconBorderMargin) / iconWidth
|
||||
} else {
|
||||
(height - iconBorderMargin) / iconHeight
|
||||
}
|
||||
|
||||
val scaledWidth = iconWidth * scale
|
||||
val scaledHeight = iconHeight * scale
|
||||
|
||||
val left = centerX - scaledWidth / 2
|
||||
val top = centerY - scaledHeight / 2
|
||||
val right = centerX + scaledWidth / 2
|
||||
val bottom = centerY + scaledHeight / 2
|
||||
val dstRect = RectF(left, top, right, bottom)
|
||||
|
||||
canvas.drawBitmap(icon, null, dstRect, null)
|
||||
}
|
||||
|
||||
|
||||
fun setProgress(progress: Int) {
|
||||
this.currentProgress = progress.coerceIn(0, maxProgress)
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setCenterIcon(@DrawableRes iconRes: Int) {
|
||||
centerIcon = BitmapFactory.decodeResource(resources, iconRes)
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setProgressColor(color: Int) {
|
||||
progressColor = color
|
||||
progressPaint.color = color
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun getProgress(): Int = currentProgress
|
||||
|
||||
fun getMaxProgress(): Int = maxProgress
|
||||
|
||||
fun setMaxProgress(max: Int) {
|
||||
maxProgress = max
|
||||
if (currentProgress > maxProgress) {
|
||||
currentProgress = maxProgress
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
|
||||
private fun dpToPx(dp: Float): Float {
|
||||
return dp * resources.displayMetrics.density
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
centerIcon?.recycle()
|
||||
}
|
||||
}
|
||||
|
|
@ -24,5 +24,19 @@
|
|||
<attr name="rightButtonSpacing" format="dimension"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CircleProgressBar" tools:ignore="ResourceName">
|
||||
<!-- 进度条颜色 -->
|
||||
<attr name="progressColor" format="color|reference" />
|
||||
<attr name="backgroundColor" format="color|reference" />
|
||||
<attr name="progressWidth" format="dimension" />
|
||||
|
||||
<!-- 中间图标 -->
|
||||
<attr name="centerIcon" format="reference" />
|
||||
|
||||
<!-- 进度相关 -->
|
||||
<attr name="maxProgress" format="integer" />
|
||||
<attr name="currentProgress" format="integer" />
|
||||
<attr name="startAngle" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
|
@ -57,4 +57,8 @@
|
|||
<color name="green_09">#ff00ff09</color>
|
||||
|
||||
|
||||
<color name="progress_green">#FF00FF5E</color>
|
||||
<color name="progress_background">#99000000</color>
|
||||
|
||||
|
||||
</resources>
|
||||
Loading…
Reference in New Issue