默认打开播放器播放视频时,视频页面的上部与下部的控制栏都是隐藏的,单击视频后显示,再单击隐藏,长按视频后暂停,再长按就播放。同时解决了一个消失与隐藏的一个小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事件给手势识别器,否则无法触发手势识别器的回调方法@Overridepublic 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);    }}

    同样,在控制栏显示时,不管是点击停止、播放按钮,还是点击下一个、上一个等按钮,都要实现上面的逻辑,即先移除消息,再重新发送延迟的消息

    

@Overridepublic 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);}