Search code examples
androidkotlinandroid-buttonandroid-progressbar

Add progressbar as compoundDrawable to button


I want to add a indeterminate progressbar to my custom button. I'm using add setCompoundDrawablesWithIntrinsicBounds to add it to left. But somehow progress bar animation doesn't appear.

//CustomButton.kt
fun addProgressbar () {
  val progressBar = ProgressBar(context)
  progressBar.isIndeterminate = true
  progressBar.animate()
  progressBar.setBackgroundColor(Color.RED)
  progressBar.layoutParams = LinearLayout.LayoutParams(
      ViewGroup.LayoutParams.WRAP_CONTENT,
      ViewGroup.LayoutParams.WRAP_CONTENT
  )
  progressBar.visibility = View.VISIBLE

  setCompoundDrawablesWithIntrinsicBounds(
      progressBar.indeterminateDrawable,
      null,
      ContextCompat.getDrawable(context, R.drawable.ic_baseline_notifications_black_24),
      null
  )
}

When I debug progressBar.isAnimating() returns false. I also tried to add a resource drawable with ContextCompat.getDrawable which works.

How can I make it work ?


Solution

  • class MyButton @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
    ) : AppCompatButton(context, attrs, defStyle) {
    
        private var progressDrawable: Drawable
    
        init {
            progressDrawable = ProgressBar(context).indeterminateDrawable.apply {
                // apply any customization on drawable. not on progress view
                setBounds(0, 0, 24.toPx, 24.toPx)
                setTint(Color.WHITE)
            }
            compoundDrawablePadding = 4.toPx
        }
    
        var isLoading: Boolean = false
            set(value) {
                if (isLoading == value) return
                field = value
    
                val (startDrawable, topDrawable, endDrawable, bottomDrawable) = compoundDrawablesRelative
                if (value) {
                    // add progress and keep others
                    setCompoundDrawablesRelative(
                        progressDrawable,
                        topDrawable,
                        endDrawable,
                        bottomDrawable
                    )
                    (progressDrawable as? Animatable)?.start()
                } else {
                    // remove progress
                    setCompoundDrawablesRelative(
                        null,
                        topDrawable,
                        endDrawable,
                        bottomDrawable
                    )
                    (progressDrawable as? Animatable)?.stop()
                }
            }
    
        override fun onDetachedFromWindow() {
            (progressDrawable as? Animatable)?.stop()
            super.onDetachedFromWindow()
        }
    }
    

    Progress button

    PS: Slowness is related to recording/encoding. It works normally.