Android DevAndroid知识Android 开发技术交流

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

2017-05-25  本文已影响275人  DevSiven

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

** 我简单说明下效果 **
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

上一篇 下一篇

猜你喜欢

热点阅读