原生VideoView使用总结
Android 上原生的控件 VideoView
当然是做视频播放的首选,使用简单,下面介绍一下自己在项目使用过程中的一些注意点.
宽高问题.
- 由
VideoView
的源码可知,不管你设置的View
的宽高是多少,VideoView
会根据视频文件的宽高重新设置View
的宽高,最终显示效果类似于ImageView
的FIT_CENTER
. - 如果想自定义宽高,做到
FIT_XY
的效果,就需要继承VideoView
重写onMeasure
方法.
- 由
播放和暂停/恢复.
播放调用
setVideoPath()
或setVideoURI()
即可,VideoView
会异步加载视频,加载完毕回调OnPreparedListener()
.如果播放本地视频,放进raw
文件夹,如video_guide.mp4
.mVideoView.setVideoPath("android.resource://" + getPackageName() + "/raw/video_guide"); mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }
暂停:
pause()
.恢复:
start()
.注意这里不要调用resume()
.
进度条.
进度检测
UI中一般会有一个
SeekBar
来显示当前播放进度,这里我采取是定时刷新的的办法:1.在
OnPreparedListener()
中设置SeekBar
的 max 值.mSeekBar.setMax(mp.getDuration());
2.通过
Handler
每秒计算SeekBar
的位置.mSeekBar.setProgress(mVideoView.getCurrentPosition()).
进度条拖动,必然是通过
OnSeekBarChangeListener()
监控.mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //建议在这里更新显示当前拖动的时间 } @Override public void onStartTrackingTouch(SeekBar seekBar) { //建议在这里(开始拖动时)停止倒计时 } @Override public void onStopTrackingTouch(SeekBar seekBar) { //建议在这里(停止拖动时)将 VideoView seekTo 当前位置. } }); 同时在 `OnPreparedListener()` 中, 为 `MediaPlayer` 设置 `OnSeekCompleteListener()` 来监听滑动停止. mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() { @Override public void onSeekComplete(MediaPlayer mp) { //同时开始倒计时 mVideoView.start(); } });
显示和隐藏 Loading 图.
如果播放网络视频,难免会遇到缓冲的情况,除了视频需要切片之外,客户端还需要监听缓冲状态以显示/隐藏 Loading 图.
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { switch (what) { case MediaPlayer.MEDIA_INFO_BUFFERING_START: //显示 Loading 图 break; case MediaPlayer.MEDIA_INFO_BUFFERING_END: //隐藏 Loading 图 break; } return false; } });
“无法加载此视频”的提示.
如果是一个无法播放的视频,会弹出一个”无法播放此视频”的 Dialog. 从体验的角度来说就算无法播放也不能用这样的 Dialog 来提示,查看源码可知, 只需要为
VideoView
设置OnErrorListener()
即可.横竖屏切换.
视频当然是全屏播放最好,此时就需要将
Activity
变为横屏.在
AndroidManifest.xml
设置当前Activity
的configChanges
属性.android:configChanges="orientation
通过代码改变当前
Activity
的横竖屏.//横屏activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //竖屏activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
在
View
或Activity
的onConfigurationChanged()
回调中处理横竖屏切换.@Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { //横屏 } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { //竖屏 } }
切换后台或打开新页面(即经过
Activity
的onStop()
生命周期.因为
VideoView
继承了SurfaceView
, 在Activity
的onStop()
生命周期中会调用surfaceDestroyed()
, 此时会释放MediaPlayer
, 所以当切换后台或打开新页面回来,视频就会重头播放,暂时还没想到解决办法.
以上就是关于原生 VideoView
的简单使用, 下一步我考虑切换到 Google 的 ExoPlayer , 如果使用顺利我会继续总结.