Чтобы начать с пользовательского представления, имейте в виду следующие моменты
Поскольку это диктует представление индикатора прогресса с текстом над ним. Поэтому выберите TextView для расширения функциональности.
Здесь анимируется фон, это означает, что наша часть прорисовки прогресса должна быть выполнена до исходного цикла прорисовки текста.
Желательно, чтобы обновление прогресса оставалось за пределами пользовательского представления.
С учетом этого пользовательское представление будет выглядеть следующим образом
class DownloadButton : androidx.appcompat.widget.AppCompatTextView {
/// constructor
private val bgPaint: Paint = Paint().apply {
color = 0xff216353.toInt()
}
private val progressPaint: Paint = Paint().apply {
color = 0xff75daad.toInt()
}
var progress: Float = 0f
override fun onDraw(canvas: Canvas?) {
// Draw before original content drawn
// Compute the dx based on the progress
// and draw 2 rects
canvas?.let {
val dx = it.width * progress
it.drawRect(RectF(0f, 0f, dx, it.height * 1f), bgPaint)
it.drawRect(RectF(dx, 0f, it.width * 1f, it.height * 1f), progressPaint)
}
super.onDraw(canvas)
}
fun updateProgress(progress: Float) {
this.progress = progress
val percent = (progress * 100).toInt()
text = "Progress $percent%"
invalidate()
}
}
Использовать его в xml как любой используемый TextView
<com.example.custom.DownloadButton
android:id="@+id/downloadButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:padding="16dp"
android:text="Download"
android:textColor="#fff"
android:textSize="20sp"
android:textStyle="bold"
android:layout_margin="16dp"
android:typeface="monospace" />
В любом месте кода, вызовите downloadButton.updateProgress (), чтобы перерисовать прогресс.
Обратите внимание, что это минимальная реализация, где мы не выполнялась оптимизация вычислений для граничных случаев (0 - 100), при которых было бы достаточно нарисовать один прямоугольник