效果图:
需求:
刚进入视频播放页时,屏幕中间有加载进度条
视频播放过程中,视频界面不动了,正在缓冲时,屏幕中间有加载进度条
private ObjectAnimator rotate; ImageView bufferProgress; int old_position = 0; //初始化的时候就开启旋转动画 rotate = ObjectAnimator.ofFloat(bufferProgress, "rotation", 0f, 360f); rotate.setRepeatCount(RotateAnimation.INFINITE); rotate.setDuration(1000); bufferProgress.setVisibility(View.VISIBLE); rotate.start(); rotate.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { bufferProgress.setVisibility(View.GONE); } @Override public void onAnimationRepeat(Animator animation) { } }); //视频播放准备好了就取消动画 videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { ... rotate.cancel(); } }); //因为播放进度条本来就有一个定时器,所以正好用这个来监听,通过判断现在和下一秒的播放进度是否相等来决定是否显示缓冲进度条 timer.schedule(new TimerTask() { @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { int currentPosition = videoView.getCurrentPosition(); if (old_position == currentPosition && videoView.isPlaying()) { bufferProgress.setVisibility(VISIBLE); rotate.start(); } else { bufferProgress.setVisibility(GONE); rotate.cancel(); } old_position = currentPosition; seekBar.setProgress(currentPosition); seekBar.setSecondaryProgress(videoView.getBufferPercentage()); currentTime.setText(dateFormat.format(new Date(currentPosition))); } }); } }, 0, 1000);
这里有些坑要注意:
1.本来我是想通过MediaPlayer.setOnBufferingUpdateListener得到缓冲进度和播放进度比较来判断是否显示,结果发现缓冲进度永远大于播放进度,即时视频卡住正在缓冲的时候,所以无法实现
2.播放进度条的定时器是一秒一秒的,如果缓冲进度条旋转的话,每秒都会回到初始位置,如果一开始设置旋转一圈的时间大于一秒,那么缓冲进度条旋转起来就像断断续续的,所以要么设置一秒旋转一圈(有些快),要么缓冲进度条是个无论从任何方向看都是一样的,这样旋转起来就像连续的