默认打开播放器播放视频时,视频页面的上部与下部的控制栏都是隐藏的,单击视频后显示,再单击隐藏,长按视频后暂停,再长按就播放。同时解决了一个消失与隐藏的一个小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);
}