其实我觉得大家只要看到标题应该就知道怎么实现了,不过还是贴一下过程, 当个记录吧.
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();
}