Android 用 ValueAnimator 实现 MediaPlayer 声音淡入淡出效果。前段时间帮朋友优化一个简单的android本地音乐播放器APP时,收集的一个相关教程。实现音乐播放,声音的淡入淡出效果。
Android 封装的 MediaPlayer 为我们提供了设置音量的方法.
public void setVolume(float leftVolume, float rightVolume)
leftVolume
和rightVolume
其实是声音的放大系数 , 取值区间为:[0,1]
- 0 表示无声, 1表示原声音大小
于是我们可以用 ValueAnimator
来实现声音淡入淡出效果.
kotlin 的实现方法
/** * 产生一个声音渐变效果,可以在暂停或者播放的时候调用 * @param from 渐变起始的声音大小,取值范围: 0-1,0表示无声,1表示声音最大 * @param to 渐变结束的声音大小,取值范围: 0-1,0表示无声,1表示声音最大 * @param doneCallback 声音渐变正常结束时的回调 */ private fun MediaPlayer.volumeGradient(from: Float, to: Float, doneCallback: (() -> Unit)? = null) { val animator = ValueAnimator.ofFloat(from, to) animator.duration = 500 animator.interpolator = LinearInterpolator() animator.addUpdateListener { val volume = it.animatedValue as Float try { //此时可能 mediaplayer 状态发生了改变,所以用try catch包裹,一旦发生错误,立马取消 setVolume(volume, volume) } catch (e: Exception) { it.cancel() } } //当淡入淡出效果结束时,将声音调回原样 animator.addListener { onAnimationCancel { mediaPlayer.setVolume(from, from) } onAnimationEnd { mediaPlayer.setVolume(from, from) doneCallback?.invoke() } animator.start() }
调用时就这样做:
//暂停播放 mediaPlayer.volumeGradient(1f, 0f) { mediaPlayer.pause() } //开始播放 mediaPlayer.start() mediaPlayer.volumeGradient(0f, 1f)
Java版本?
interface DoneCallBack { void onComplete(); } public static void volumeGradient(final MediaPlayer mediaPlayer, final float from, final float to, @Nullable DoneCallBack doneCallBack) { ValueAnimator animator = ValueAnimator.ofFloat(from, to); animator.setDuration(500); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(it -> { float volume = (float) it.getAnimatedValue(); try { //此时可能 mediaPlayer 状态发生了改变,所以用try catch包裹,一旦发生错误,立马取消 mediaPlayer.setVolume(volume, volume); } catch (Exception e) { it.cancel(); } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { mediaPlayer.setVolume(from, from); if (doneCallBack != null) { doneCallBack.onComplete(); } } @Override public void onAnimationCancel(Animator animation) { try { mediaPlayer.setVolume(from, from); } catch (Exception e) { //忽略 } } @Override public void onAnimationRepeat(Animator animation) { } }); animator.start(); }
就这样是不是很简单?
最新评论