android-studiokotlinaudiowaveform

How to change wave form colour Android Studio kotlin


I've been following a tutorial on Youtube for a audio recorder with a Wave Form. I would like to know how to change the colour of the wave form. I want it in blue.

Here's the class' code

    class WaveformView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {

    private var paint = Paint()
    private var amplitudes = ArrayList<Float>()
    private var spikes = ArrayList<RectF>()

    private var radius = 6f
    private var w = 9f

    private  var sw = 0f
    private  var sh = 400f
    private  var d = 6f

    private var maxSpikes = 0


    init {
        paint.color = Color.rgb(244, 81, 3)

        sw  = resources.displayMetrics.widthPixels.toFloat()

        maxSpikes = (sw / (w+d)).toInt()
    }

    fun addAmplitude(amp: Float){
        var norm  = (amp.toInt() / 7).coerceAtMost(400).toFloat()
        amplitudes.add(norm)

        spikes.clear()
        var amps: List<Float> = amplitudes.takeLast(maxSpikes)

        for(i in amps.indices){

            var left = sw - i*(w+d)
            var top = sh/2 - amps[i]/2
            var right: Float = left + w
            var bottom: Float = top +  amps[i]

            spikes.add(RectF(left, top, right, bottom))

        }

        invalidate()
    }

    fun clear() : ArrayList<Float>{
        var amps: ArrayList<Float> = amplitudes.clone() as ArrayList<Float>
        amplitudes.clear()
        spikes.clear()
        invalidate()

        return amps

    }

    override fun draw(canvas: Canvas?) {
        super.draw(canvas)
        spikes.forEach {
            canvas?.drawRoundRect(it, radius, radius, paint)
        }
    }
}

I've already tried to change it in the XML layout file, but it hasn't worked. So there won't be any point in pasting it here.


Solution

  • Add a color property that changes the Paint's color:

    var waveFormColor: Int
        @ColorInt get() = paint.color
        set(@ColorInt value) { paint.color = value }
    

    Then you can modify the color from outside the class:

    myWaveformView.waveFormColor = Color.parseColor("#FF0080")
    
    // or
    
    myWaveformView.waveFormColor = "#FF0080".toColorInt()
    
    // or
    
    myWaveformView.waveFormColor = Color.rgb(255, 0, 128)
    

    The @ColorInt is optional and you can omit it. There are certain cases where it can help Lint prevent you from passing the wrong type of value.

    If you want to make it so you can set the color from XML, first create an attrs.xml file in res/values if you don't have one yet, and add an entry for theming your custom view:

    <resources>
       <declare-styleable name="WaveformView">
           <attr name="waveform_color" format="color"/>
       </declare-styleable>
    </resources>
    

    In your view layout file, you can use this attribute using app:waveform_color="@color/someColor".

    Then update the init block of your custom view to use that XML attribute:

    init {
        context.theme.obtainStyledAttributes(attrs, R.styleable.WaveformView, 0, 0).use {
            paint.color = it.getColor(R.styleable.WaveformView_waveform_color, Color.rgb(244, 81, 3))
        }
    
        sw  = resources.displayMetrics.widthPixels.toFloat()
    
        maxSpikes = (sw / (w+d)).toInt()
    }