刚刚听到淡入淡出这个效果还是挺懵逼的,后面有同事告诉我试下一个场景:当手机用网易云音乐播放音乐的时候,如果这时候听微信语音中断播放音乐,这时候你会细心发现网易音乐的静音和播放都有渐入渐出效果。试下还真的有这种细节上的效果~
** 我简单说明下效果 **
1、淡入。从0到1过程。音量声音不会马上变化,是有一个过度的增大
2、淡出。从1到0过程。音量声音不会马上变化,是有一个过度的降低
所以下面看下怎么实现的:
一、SOURCE
整个控制器大概是以下调用逻辑:
底层其实就是由handler去做Delayed动态增大或者降低音量,逻辑原理都比较好理解,所以这里笔者就不详细介绍,笔者抽成一个简化版本代码贴上来,希望可以给读者一些参考价值~
二、CODE
/**
* 音量淡入淡出管理者
* Created by siven on 17/3/22.
*/
public class MuteVolumeManager {
// action
private static final int ACTION_RESTORE_VALUE = 1000;
private static final int ACTION_STOP_VALUE = 1001;
// 淡出与淡出时间
private int restoreTime = 2000; // 恢复 淡入时间为2秒
private int stopTime = 1000; // 静音 淡出时间为1秒
private float muteCurVolume = 0f;
private float muteTargetVolume = 0f;
private float unMuteCurVolume = 0f;
private float unMuteTargetVolume = 0f;
private boolean isMuteing = false;
private boolean isUnMuteing = false;
// listenter
private VolumeListenter volumeListenter;
public void setVolumeListenter(VolumeListenter volumeListenter) {
this.volumeListenter = volumeListenter;
}
// handler control
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == ACTION_RESTORE_VALUE){
if (muteCurVolume < muteTargetVolume) {
muteCurVolume += 0.1f;
if (muteCurVolume > 1) {
muteCurVolume = 1;
}
if (muteCurVolume < muteTargetVolume){
muteCurVolume = muteTargetVolume;
}
// Logger.d("siven","实时恢复音量 " + muteCurVolume);
if (muteCurVolume < muteTargetVolume) {
notifyVolumeChange(muteCurVolume);//最大1.0,是个百分比
handler.sendEmptyMessageDelayed(ACTION_RESTORE_VALUE, restoreTime/10);//2秒恢复音量100%音量
}else{
muteCurVolume = muteTargetVolume;
notifyVolumeChange(muteCurVolume);//最大1.0,是个百分比
if (volumeListenter!=null && isUnMuteing) volumeListenter.onCompleteUnMute(muteCurVolume);
isUnMuteing = false;
}
}else if (muteCurVolume >= muteTargetVolume){
notifyVolumeChange(muteTargetVolume);//最大1.0,是个百分比
// Logger.d("siven","实时恢复音量 " + muteTargetVolume);
if (volumeListenter!=null && isUnMuteing) volumeListenter.onCompleteUnMute(muteCurVolume);
isUnMuteing = false;
}
}else if (msg.what == ACTION_STOP_VALUE){
if (unMuteCurVolume > unMuteTargetVolume){
unMuteCurVolume -=0.1;
if (unMuteCurVolume <0){unMuteCurVolume = 0;}
notifyVolumeChange(unMuteCurVolume);
// Logger.d("siven","实时静音音量 " + unMuteCurVolume);
if (unMuteCurVolume > unMuteTargetVolume) {
handler.sendEmptyMessageDelayed(ACTION_STOP_VALUE, stopTime/10);//0.5秒恢复音量100%音量
}else{
if (volumeListenter!=null && isMuteing) volumeListenter.onCompleteMute(unMuteCurVolume);
isMuteing = false;
}
}else{
notifyVolumeChange(0f);//静音
if (volumeListenter!=null && isMuteing) volumeListenter.onCompleteMute(unMuteCurVolume);
isMuteing = false;
}
}
}
};
/**
* 恢复音量,淡入效果
*/
public void unMute(float curVolume,float tagetVolume){
if (isUnMuteing) return;
isUnMuteing = true;
this.muteTargetVolume = tagetVolume;
this.muteCurVolume = curVolume;
handler.sendEmptyMessage(ACTION_RESTORE_VALUE);
}
/**
* 静音,淡出效果
*/
public void mute(float curVolume){
if (isMuteing) return;
isMuteing = true;
this.unMuteCurVolume = curVolume;
this.unMuteTargetVolume = 0f;
handler.sendEmptyMessage(ACTION_STOP_VALUE);
}
private void notifyVolumeChange(float volume){
if (volumeListenter != null){
volumeListenter.onVolumeChange(volume);
}
}
public interface VolumeListenter{
public void onCompleteMute(float curVolume);
public void onCompleteUnMute(float curVolume);
public void onVolumeChange(float volume);
}
}
这里有说明下VolumeListenter里面三个回调作用,** onCompleteMute 当发生静音(即淡出)的时候,淡出结束完成后回调。 onCompleteUnMute则是相反,淡入结束完成后回调。 onVolumeChange **则是淡入淡出时音量变化回调,这时候只需要在外部调用者控制mediaplayer音量即可,详情看下面举例。
三、DEMO
//.....
private MuteVolumeManager volumeManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initMediaPlayer();
initManager();
muteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
volumeManager.mute(0f);
}
});
unMuteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
volumeManager.mute(0f,0.5f);// 我只需要恢复到一半
}
});
}
private void initManager() {
volumeManager = new MuteVolumeManager();
volumeManager.setVolumeListenter(new VolumeListenter() {
public void onCompleteMute(float curVolume) {
Log.i("siven","静音完成,当前音量为: " + curVolume);
}
public void onCompleteUnMute(float curVolume) {
Log.i("siven","恢复音量完成,当前音量为: " + curVolume);
}
public void onVolumeChange(float volume) {
// 动态设置音量
mediaPlayer.setVolume(volume,volume);
}
});
}
private void initMediaPlayer(){
//...
}
//.....
三、END
技术、创业、架构等等...有想法欢迎交流
by siven(qq:708854877 email:sy.wu@foxmail.com)
2017.5.25