Waveform seek bar loading animation.

This commit is contained in:
Anton Chekulaev 2020-10-12 17:36:58 +11:00
parent cb67bfa4a5
commit 066234a30a
2 changed files with 33 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import android.graphics.PorterDuff
import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.AnimatedVectorDrawable
import android.media.MediaDataSource import android.media.MediaDataSource
import android.os.Build import android.os.Build
import android.os.Handler
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.View.OnTouchListener import android.view.View.OnTouchListener
@ -57,11 +58,12 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
private var downloadListener: SlideClickListener? = null private var downloadListener: SlideClickListener? = null
private var audioSlidePlayer: AudioSlidePlayer? = null private var audioSlidePlayer: AudioSlidePlayer? = null
// private var backwardsCounter = 0
/** Background coroutine scope that is available when the view is attached to a window. */ /** Background coroutine scope that is available when the view is attached to a window. */
private var asyncCoroutineScope: CoroutineScope? = null private var asyncCoroutineScope: CoroutineScope? = null
private val loadingAnimation: SeekBarLoadingAnimation
constructor(context: Context): this(context, null) constructor(context: Context): this(context, null)
constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0) constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0)
@ -121,6 +123,9 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
container.setBackgroundColor(typedArray.getColor(R.styleable.MessageAudioView_widgetBackground, Color.TRANSPARENT)) container.setBackgroundColor(typedArray.getColor(R.styleable.MessageAudioView_widgetBackground, Color.TRANSPARENT))
typedArray.recycle() typedArray.recycle()
} }
loadingAnimation = SeekBarLoadingAnimation(this, seekBar)
loadingAnimation.start()
} }
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
@ -312,6 +317,7 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
android.util.Log.d(TAG, "RMS: ${rmsValues.joinToString()}") android.util.Log.d(TAG, "RMS: ${rmsValues.joinToString()}")
post { post {
loadingAnimation.stop()
seekBar.sampleData = rmsValues seekBar.sampleData = rmsValues
if (totalDurationMs > 0) { if (totalDurationMs > 0) {
@ -332,6 +338,30 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
} }
} }
private class SeekBarLoadingAnimation(
private val hostView: View,
private val seekBar: WaveformSeekBar): Runnable {
companion object {
private const val UPDATE_PERIOD = 500L // In milliseconds.
private val random = Random()
}
fun start() {
stop()
run()
}
fun stop() {
hostView.removeCallbacks(this)
}
override fun run() {
seekBar.sampleData = (0 until 64).map { random.nextFloat() * 0.5f }.toFloatArray()
hostView.postDelayed(this, UPDATE_PERIOD)
}
}
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private class InputStreamMediaDataSource: MediaDataSource { private class InputStreamMediaDataSource: MediaDataSource {

View File

@ -33,6 +33,7 @@ class WaveformSeekBar : View {
} }
private val sampleDataHolder = SampleDataHolder(::invalidate) private val sampleDataHolder = SampleDataHolder(::invalidate)
/** An array if normalized to [0..1] values representing the audio signal. */
var sampleData: FloatArray? var sampleData: FloatArray?
get() { get() {
return sampleDataHolder.getSamples() return sampleDataHolder.getSamples()
@ -282,6 +283,7 @@ class WaveformSeekBar : View {
fun setSamples(sampleData: FloatArray?) { fun setSamples(sampleData: FloatArray?) {
sampleDataFrom = sampleDataTo sampleDataFrom = sampleDataTo
sampleDataTo = sampleData sampleDataTo = sampleData
progress = 0f
animation?.cancel() animation?.cancel()
animation = ValueAnimator.ofFloat(0f, 1f).apply { animation = ValueAnimator.ofFloat(0f, 1f).apply {