代码已托管至码云上,有兴趣的小伙伴可以下载看看,IDE是Android studio 2.3.2
https://git.oschina.net/joy_yuan/MobilePlayer
常见的手机播放器,都有屏幕上下滑动改变音量大小的功能,在此也实现下:
原理是:
1、从手指触碰屏幕,到离开屏幕,计算滑动的高度差,然后拿这个高度差与屏幕的高对比,最后结合总音量,得到改变的音量,具体的公式如下 :
改变的音量=(滑动距离差/屏幕总高度)*总音量
结束滑动后的音量=触碰屏幕时的音量+改变的音量
根据这个来改变音量与seekbar的显示进度
2、在手指触碰到屏幕时,会回调onTouchEvent方法,在这个方法里,有个参数event,这个参数可以获取到手指是上滑还是下滑
3、当手指一触碰屏幕,此时从event.getY()获取开始滑动时的Y轴值,并获取此时的声音值
4、当手指离开屏幕时,根据event.getY()获取离开时的Y轴值,前面的Y轴值-这时的Y轴值,就得到距离
5、根据上面的算法获取接收后的音量,然后设置对应的音量与seekbar进度即可.
具体代码如下:
private float startY; //在屏幕上滑动调节音量时,开始的Y轴值 private float touchRange; //屏幕的高,因为涉及到横竖屏切换,到时候会取小的值 private int touchVoice; //滑动时的音量 //利用onTouchEvent,传递event事件给手势识别器,否则无法触发手势识别器的回调方法 @Override public boolean onTouchEvent(MotionEvent event) { dector.onTouchEvent(event); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: startY=event.getY(); currentVoice=audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); //获取滑动开始时的音量 touchRange=Math.min(screenHeight,screenWidth); handler.removeMessages(HIDEVIDEO); break; case MotionEvent.ACTION_MOVE: float endY=event.getY(); //滑动的距离 float distance=startY-endY; //相对滑动的距离 //float changeVoice=(distance/touchRange)*maxVoice; //改变的音量 Log.i(TAG, "onTouchEvent: move里改变的距离"+distance); //int voice= (int) Math.min(Math.max(touchVoice+changeVoice,0),maxVoice); //改变后的音量 // if (changeVoice!=0){ //当改变的音量不为0时,才去改变音量 // setVoice(voice,false); // } break; case MotionEvent.ACTION_UP: float upY=event.getY(); float upDistance=startY-upY; float changeVoice=(upDistance/touchRange)*maxVoice; //改变的音量 Log.i(TAG, "onTouchEvent: 取消滑动时的距离"+upDistance); int voice= (int) Math.min(Math.max(touchVoice+changeVoice,0),maxVoice); //改变后的音量 if (changeVoice!=0){ //当改变的音量不为0时,才去改变音量 setVoice(voice,false); } handler.sendEmptyMessageDelayed(HIDEVIDEO,3000); break; } return super.onTouchEvent(event); }
同时Android的物理键也有增大、减小音量的功能,那么在这里也需要监听下物理键的回调方法,来改变音量大小以及seekbar的进度条
/** * 当按手机的增加音量、减少音量时,相应的改变音量与进度条 * @param keyCode * @param event * @return */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode==KeyEvent.KEYCODE_VOLUME_DOWN){ currentVoice--; setVoice(currentVoice,false); handler.removeMessages(HIDEVIDEO); handler.sendEmptyMessageDelayed(HIDEVIDEO,3000); return true; }else if (keyCode==KeyEvent.KEYCODE_VOLUME_UP){ currentVoice++; setVoice(currentVoice,false); handler.removeMessages(HIDEVIDEO); handler.sendEmptyMessageDelayed(HIDEVIDEO,3000); return true; //如果返回false,那么seekbar变化,同时系统的音量条也会出现,不好看。 } return super.onKeyDown(keyCode, event); }