Android 控制你的音量淡入淡出吧~

作者: DevSiven | 来源:发表于2017-05-25 15:00 被阅读275次

    刚刚听到淡入淡出这个效果还是挺懵逼的,后面有同事告诉我试下一个场景:当手机用网易云音乐播放音乐的时候,如果这时候听微信语音中断播放音乐,这时候你会细心发现网易音乐的静音和播放都有渐入渐出效果。试下还真的有这种细节上的效果~

    ** 我简单说明下效果 **
    1、淡入。从0到1过程。音量声音不会马上变化,是有一个过度的增大
    2、淡出。从1到0过程。音量声音不会马上变化,是有一个过度的降低

    所以下面看下怎么实现的:

    一、SOURCE

    整个控制器大概是以下调用逻辑:

    muteVolumeManager.png

    底层其实就是由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

    相关文章

      网友评论

        本文标题:Android 控制你的音量淡入淡出吧~

        本文链接:https://www.haomeiwen.com/subject/goxzxxtx.html