Android上的音频播放动画

时间:2018-04-02 06:42:59

标签: android performance animation

我想知道它们是如何填充代表音频记录的视图的“播放”部分的。以下是Telegram的一个例子:

enter image description here

表示音频记录的视图的初始颜色为灰色。演奏的部分充满了蓝色。

我如何实施这样的事情?我会存储两个图像。第一个表示处于未播放状态的音频记录,第二个表示处于播放状态的相同记录。

未播放状态:

enter image description here

播放状态:

enter image description here

然后我会创建一个FrameLayout,其中包含两个View并使用the clip drawable API逐渐显示播放的部分。这是我的代码:

clipped_view_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="15000"
    android:propertyName="level"
    android:valueTo="10000"
    android:valueType="intType" />

played_clip.xml

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/played"
    android:gravity="left" />

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    android:orientation="vertical"
    tools:context="ru.maksim.sample.MainActivity">

    <Button
        android:id="@+id/play"
        android:text="Play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/not_played" />

        <ImageView
            android:id="@+id/clippedView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/played_clip" />

    </FrameLayout>
</LinearLayout>

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        play.setOnClickListener({ play() })
    }

    private fun play() {
        val clippedDrawable = clippedView.background as ClipDrawable
        Log.d(TAG, "level=${clippedDrawable.level}")
        val animator = AnimatorInflater.loadAnimator(this, R.animator.clipped_view_animator)
        animator.setTarget(clippedDrawable)
        animator.start()
    }
}

视频: https://youtu.be/9X8Yb9aKqmQ

我的方法有效。但是,我想知道是否有更好的方法来做我所做的事情(在性能,代码行数等方面)。顺便说一句,从我的视频中可以清楚地看出,我超过了每帧限制16毫秒(三星Galaxy Tab 4和Android 5.0.2)。在现实世界的应用程序中可能会更糟。

1 个答案:

答案 0 :(得分:1)

您的代码似乎完美地执行了该功能。但是,有时库比本机代码更有效。您可以参考这些库来实现您的功能。

  1. WaveForm
  2. Yalantis Horizon Wave
  3. Audio-Recorder-Visualization
  4. Semantive Waveform
  5. WaveInApp
  6. WaveformControl
  7. 库没有完全相同的实现,您可能需要调整它以满足您的要求。我找到了一个similar question,在我开展类似项目时帮助了我。答案使用本机代码来显示音频波形。您可以参考this answer