You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Material库LinearProgressIndicator的进度指示条内添加标签?

在LinearProgressIndicator内部添加进度标签的实现方案

要在LinearProgressIndicator的指示条内部添加类似示例图的进度数值标签,可通过以下两种方案实现:

方法一:ConstraintLayout叠加TextView实现

利用布局叠加,将文本标签与进度条绑定,并通过代码同步进度与文本位置:

布局代码

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:id="@+id/progressIndicator"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="65"
        app:trackColor="@color/background_color"
        app:trackThickness="16dp"
        app:indicatorColor="@color/black"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <TextView
        android:id="@+id/progressLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="65%"
        android:textColor="@color/white"
        android:textSize="12sp"
        app:layout_constraintStart_toStartOf="@id/progressIndicator"
        app:layout_constraintTop_toTopOf="@id/progressIndicator"
        app:layout_constraintBottom_toBottomOf="@id/progressIndicator"
        android:layout_marginStart="8dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

代码同步逻辑

val progressIndicator = findViewById<LinearProgressIndicator>(R.id.progressIndicator)
val progressLabel = findViewById<TextView>(R.id.progressLabel)

// 静态设置进度与文本
val targetProgress = 65
progressIndicator.progress = targetProgress
progressLabel.text = "$targetProgress%"

// 动态更新进度时同步文本位置
val animator = ValueAnimator.ofInt(0, 100)
animator.duration = 1000
animator.addUpdateListener { animation ->
    val currentProgress = animation.animatedValue as Int
    progressIndicator.progress = currentProgress
    progressLabel.text = "$currentProgress%"
    // 让文本跟随进度条末端移动,避免超出指示范围
    val indicatorWidth = progressIndicator.width * currentProgress / 100
    progressLabel.translationX = indicatorWidth - progressLabel.width - 8f
}
animator.start()

方法二:自定义LinearProgressIndicator控件

通过自定义控件,在绘制进度条时直接将文本绘制在指示条内部,效果更贴合:

自定义控件代码

class LabeledLinearProgressIndicator @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = com.google.android.material.R.attr.linearProgressIndicatorStyle
) : LinearProgressIndicator(context, attrs, defStyleAttr) {

    private val textPaint = Paint().apply {
        color = ContextCompat.getColor(context, android.R.color.white)
        textSize = resources.getDimension(R.dimen.progress_label_size)
        textAlign = Paint.Align.CENTER
        isAntiAlias = true
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val progressRate = progress.toFloat() / max.toFloat()
        val indicatorWidth = width * progressRate
        val centerY = height / 2f
        val progressText = "${(progressRate * 100).toInt()}%"
        val textWidth = textPaint.measureText(progressText)

        // 确保文本不会超出指示条范围时再绘制
        if (indicatorWidth > textWidth + 16f) {
            val textX = indicatorWidth - textWidth / 2 - 8f
            canvas.drawText(
                progressText,
                textX,
                centerY - (textPaint.ascent() + textPaint.descent()) / 2,
                textPaint
            )
        }
    }
}

布局中使用自定义控件

<com.yourpackage.LabeledLinearProgressIndicator
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="65"
    app:trackColor="@color/background_color"
    app:trackThickness="16dp"
    app:indicatorColor="@color/black"/>

内容的提问来源于stack exchange,提问作者WHOATEMYNOODLES

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:00:48