默认打开播放器播放视频时,视频页面的上部与下部的控制栏都是隐藏的,单击视频后显示,再单击隐藏,长按视频后暂停,再长按就播放。同时解决了一个消失与隐藏的一个小bug
代码已托管在码云上,可以下载来看,地址:
https://git.oschina.net/joy_yuan/MobilePlayer
一、实现显示与隐藏控制栏
要在手机上识别单击、双击,长按等手势,安卓有个专门的类来处理,即GestureDetector---手势识别器。要使用手势识别器,就有如下3步
1、声明识别器,实例化识别器
2、重写识别器里的单击、双击,长按方法
3、将点击屏幕产生的回调事件,作为参数传递给识别器的onTouchEvent(event),然后在第2步中处理特定的点击事件回调方法
在显示控制栏后,如果三秒没有操作,则自动隐藏控制栏,利用handler的延迟发送消息机制来实现。
具体代码如下:
private GestureDetector dector; // 手势识别器
dector=new GestureDetector(this,new GestureDetector.SimpleOnGestureListener(){
/**
* 长按触发的回调函数
* @param e
*/
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
startAndPause();
Toast.makeText(SystemVideoPlayer.this,"长按里屏幕",Toast.LENGTH_SHORT).show();
}
/**
* 双击触发的函数
* @param e
* @return
*/
@Override
public boolean onDoubleTap(MotionEvent e) {
//Toast.makeText(SystemVideoPlayer.this,"双击了屏幕",Toast.LENGTH_SHORT).show();
isMediaControllerShow();
return super.onDoubleTap(e);
}
/**
* 单击触发的函数
* @param e
* @return
*/
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
//Toast.makeText(SystemVideoPlayer.this,"单击了屏幕",Toast.LENGTH_SHORT).show();
handler.removeMessages(HIDEVIDEO);
isMediaControllerShow();
if (isShow){
handler.sendEmptyMessageDelayed(HIDEVIDEO,3000);
}
return super.onSingleTapConfirmed(e);
}
});
//利用onTouchEvent,传递event事件给手势识别器,否则无法触发手势识别器的回调方法
@Override
public boolean onTouchEvent(MotionEvent event) {
dector.onTouchEvent(event);
return super.onTouchEvent(event);
}
在这里通过单击、双击、长按的方式,来使控制器栏的visiable是显示还是隐藏。
二、解决产生的bug
当我们单击视频后,显示了控制栏,然后拖动seekbar进度条不放,三秒后,控制栏会消失,这是我们拖动控制栏还是可以控制视频的播放进度。这样的用户体验很差。
解决方案是,在seekbar的变化监听中,当用户点击了seekbar后,就通过handler的removeMessages(HIDDENVIDEO)来移除发送的隐藏控制栏的消息。而在用户离开seekbar后的回调方法中,重新发送延迟三秒的隐藏可控制栏的消息,具体代码如下:
/**
* 视频播放框中的进度条拖拽变化的监听
*/
class VideoOnSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
/**
* 手指在seekbar上滑动时触发
* @param seekBar
* @param progress
* @param fromUser 是否是人为的滑动导致的seekbar变化,系统自动滑动也会导致这个回调方法
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
videoview.seekTo(progress); //可以查看mediaplayer的声明周期图,里面有这个方法。
}
}
/**
* 点击seekbar时触发
* @param seekBar
*/
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//当手在点击seekbar时,阻止handler发消息去隐藏控制栏
handler.removeMessages(HIDEVIDEO);
}
/**
* 离开seekbar时触发
* @param seekBar
*/
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//当手离开seekbar时,触发handler发消息去隐藏控制栏
handler.sendEmptyMessageDelayed(HIDEVIDEO,3000);
}
}
同样,在控制栏显示时,不管是点击停止、播放按钮,还是点击下一个、上一个等按钮,都要实现上面的逻辑,即先移除消息,再重新发送延迟的消息
@Override
public void onClick(View v) {
if ( v == btnVoice ) {
// Handle clicks for btnVoice
} else if ( v == switchPlayer ) {
// Handle clicks for switchPlayer
} else if ( v == btExit ) {
// Handle clicks for btExit 退出
finish();
} else if ( v == btVideoPre ) {
// Handle clicks for btVideoPre 播放上一个视频
if (medialist!=null&&medialist.size()>0){
position-=1;
if (position<=0){
position=medialist.size()-1;
}
MediaItem mediaitem=medialist.get(position);
tvName.setText(mediaitem.getName());
videoview.setVideoPath(mediaitem.getData());
}else if (uri!=null){
tvName.setText(uri.toString());
videoview.setVideoURI(uri);
}
} else if ( v == btVideoStartPause ) {
// Handle clicks for btVideoStartPause 播放暂停与启动
startAndPause();
} else if ( v == btNext ) {
// Handle clicks for btNext 播放下一个
if (medialist!=null&&medialist.size()>0){
position+=1;
if (position>=medialist.size()){
position=0;
}
MediaItem mediaItem = medialist.get(position);
tvName.setText(mediaItem.getName());
videoview.setVideoPath(mediaItem.getData());
}else if (uri!=null){
//把上一个下一个按钮设置灰色
tvName.setText(uri.toString());
videoview.setVideoURI(uri);
btNext.setEnabled(false);
btNext.setBackgroundResource(R.drawable.btn_next_gray);
}
} else if ( v == btVideoSwitchScreen ) {
// Handle clicks for btVideoSwitchScreen
}
handler.removeMessages(HIDEVIDEO);
handler.sendEmptyMessageDelayed(HIDEVIDEO,3000);
}
转载于:https://blog.51cto.com/cm0425/1949131