https://juejin.im/user/593f7b33fe88c2006a37eb9b
https://github.com/TanJiaJunBeyond/CircularArcProgressView
效果图
属性
使用
implementation ‘com.tanjiajun.widget:CircularArcProgressView:1.0.2’
}
android:id=“@+id/capv_first”
android:layout_width=“0dp”
android:layout_height=“30dp”
android:layout_marginStart=“16dp”
android:layout_marginTop=“16dp”
android:layout_marginEnd=“16dp”
app:capv_background_color=“@color/circular_arc_progress_view_first_background_color”
app:capv_is_show_progress_text=“true”
app:capv_percent=“0.8”
app:capv_progress_color=“@color/circular_arc_progress_view_first_progress_color”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“parent” />
* Set percent to show the progress.
*/
var percent: Float = 0f
set(value) {
var percent = value
if (percent < 0f)
{percent = 0f
} else if (percent > 1f) {
percent = 1f
}
if (percent != field) {
field = percent
invalidate()
}
}
init {
attrs?.let { set ->
context.obtainStyledAttributes(set, R.styleable.CircularArcProgressView).apply {
bgColor =
getColor(R.styleable.CircularArcProgressView_capv_background_color, Color.BLACK)
progressColor =
getColor(R.styleable.CircularArcProgressView_capv_progress_color, Color.RED)
progressTextColor =
getColor(
R.styleable.CircularArcProgressView_capv_progress_text_color,
Color.WHITE
)
getFloat(R.styleable.CircularArcProgressView_capv_percent, 0f).let {
percent = it
}
isShowProgressText =
getBoolean(
R.styleable.CircularArcProgressView_capv_is_show_progress_text,
false
)
recycle()
}
}
}
val saveCount = canvas.saveLayer(0f, 0f, width.toFloat(), height.toFloat(), null)
// Draw background.
backgroundRectF.left = paddingStart.toFloat()
backgroundRectF.top = paddingTop.toFloat()
backgroundRectF.right = width – paddingEnd.toFloat()
backgroundRectF.bottom = height – paddingBottom.toFloat()
canvas.drawRoundRect(backgroundRectF, halfHeight, halfHeight, backgroundPaint)
TextPaint().apply {
isAntiAlias = true
isDither = true
style = Paint.Style.FILL
color = progressTextColor
}
}
progressRectF.left = -backgroundRectF.width() + percent * width
progressRectF.top = backgroundRectF.top
progressRectF.right = progressRectF.left + backgroundRectF.width()
progressRectF.bottom = backgroundRectF.bottom
canvas.drawRoundRect(progressRectF, halfHeight, halfHeight, progressPaint)
canvas.restoreToCount(saveCount)
progressTextPaint.run {
textSize = halfHeight
fontMetrics.let {
val progressText = (percent * 100).toInt().toString() + “%”
canvas.drawText(
progressText,
percent * width – progressTextPaint.measureText(progressText) – height / 5f,
halfHeight – it.descent + (it.descent – it.ascent) / 2f,
progressTextPaint
)
}
}
}
* Start animator.
*
* @param timeInterpolator the interpolator to be used by this animation. The default value is
* android.view.animation.AccelerateInterpolator.
*
* @param duration the length of the animation.
*/
@JvmOverloads
fun startAnimator(
timeInterpolator: TimeInterpolator? = AccelerateInterpolator(),
duration: Long
) =
with(ObjectAnimator.ofFloat(this, “percent”, 0f, percent)) {
interpolator = timeInterpolator
this.duration = duration
start()
}
来源
源码
CLEAR (0),
SRC (1),
DST (2),
SRC_OVER (3),
DST_OVER (4),
SRC_IN (5),
DST_IN (6),
SRC_OUT (7),
DST_OUT (8),
SRC_ATOP (9),
DST_ATOP (10),
XOR (11),
DARKEN (16),
LIGHTEN (17),
MULTIPLY (13),
SCREEN (14),
ADD (12),
OVERLAY (15);
Mode(int nativeInt) {
this.nativeInt = nativeInt;
}
/**
* @hide
*/
@UnsupportedAppUsage
public final int nativeInt;
}
TextPaint().apply {
isAntiAlias = true
isDither = true
style = Paint.Style.FILL
color = progressTextColor
}
}
lazy(initializer: () -> T)
private var initializer: (() -> T)? = initializer
@Volatile private var _value: Any? = UNINITIALIZED_VALUE
// final field is required to enable safe publication of constructed instance
private val lock = lock ?: this
override val value: T
get() {
val _v1 = _value
if (_v1 !== UNINITIALIZED_VALUE) {
@Suppress(“UNCHECKED_CAST”)
return _v1 as T
}
return synchronized(lock) {
val _v2 = _value
if (_v2 !== UNINITIALIZED_VALUE) {
@Suppress(“UNCHECKED_CAST”) (_v2 as T)
} else {
val typedValue = initializer!!()
_value = typedValue
initializer = null
typedValue
}
}
}
override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
override fun toString(): String = if (isInitialized()) value.toString() else “Lazy value not initialized yet.”
private fun writeReplace(): Any = InitializedLazyImpl(value)
}
lazy(mode: LazyThreadSafetyMode, initializer: () -> T)
when (mode) {
LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)
LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)
LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
}
SYNCHRONIZED,
PUBLICATION,
NONE,
}
lazy(lock: Any?, initializer: () -> T)
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
// 省略实现代码
}
@JvmOverloads
public CircularArcProgressView(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
// 省略实现代码
}
@JvmOverloads
public CircularArcProgressView(@NotNull Context context, @Nullable AttributeSet attrs) {
// 省略实现代码
}
@JvmOverloads
public CircularArcProgressView(@NotNull Context context) {
// 省略实现代码
}
}
喜欢 就关注吧,欢迎投稿!
本网站文章均为原创内容,并可随意转载,但请标明本文链接
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/kotlin的自定义view,实现带弧形的进度条/