CustomVideoView
--这个自定义view类并不是很重要,就比原生的VideoView多了一步重新计算高度。
import android.content.Context;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.VideoView;
/**
* 视频播放,主要是因为手机的大小很多,不能保证原生的VideoView能实现全屏
* Created by lgl on 16/2/18.
*/
public class CustomVideoView extends VideoView {
public CustomVideoView(Context context) {
super(context);
}
public CustomVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//我们重新计算高度
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
super.setOnPreparedListener(l);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
}
感谢:
Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
接下来,是我真正在项目中的运用:
MainPageVideoView
package com.zuji.entrance.widget;
import android.content.Context;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.constraint.ConstraintLayout;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.VideoView;
import com.zuji.library.R;
/**
* Created by fangyc on 2018/7/6.
*/
public class MainPageVideoView extends ConstraintLayout {
VideoView videoView;
ImageView img_player_icon;
// ImageView img_cover;
public MainPageVideoView(Context context) {
this(context, null);
}
public MainPageVideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MainPageVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
View rootView = LayoutInflater.from(context).inflate(R.layout.zuji_main_page_video_widget, this);
initViews(rootView);
initEvents();
}
private void initViews(View rootView) {
videoView = rootView.findViewById(R.id.video_content);
videoView.setZOrderMediaOverlay(true);
// img_cover = rootView.findViewById(R.id.img_video_cover);
img_player_icon = rootView.findViewById(R.id.img_video_player_icon);
}
private void initEvents() {
//解决黑屏
// 这段代码的关键是MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START这个变量,
// Android SDK中给出的注释是:这个状态表示展现了用于渲染的第一帧视频,
// 也就是这个时候才真正将视频帧展示到了屏幕上。
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
videoView.setBackgroundColor(Color.TRANSPARENT);
return true;
}
});
}
});
//循环播放
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
stopPlay();
}
});
//点击播放
img_player_icon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startPlay();
}
});
}
public void startPlay() {
// videoView.setVisibility(View.VISIBLE);
img_player_icon.setVisibility(View.GONE);
//设置播放加载路径
videoView.setVideoURI(Uri.parse("android.resource://" + videoView.getContext().getPackageName() + "/" + R.raw.track_guide_video_zh));
//播放
videoView.start();
}
public void stopPlay() {
img_player_icon.setVisibility(View.VISIBLE);
//暂停
videoView.pause();
}
}
zuji_main_page_video_widget.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="@+id/video_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/zuji_last_video_bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--<ImageView
android:id="@+id/img_video_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/zuji_last_video_bg"
app:layout_constraintBottom_toBottomOf="@+id/video_content"
app:layout_constraintEnd_toEndOf="@+id/video_content"
app:layout_constraintStart_toStartOf="@+id/video_content"
app:layout_constraintTop_toTopOf="@+id/video_content" />-->
<ImageView
android:id="@+id/img_video_player_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/zuji_guide_player_icon"
app:layout_constraintBottom_toBottomOf="@+id/video_content"
app:layout_constraintEnd_toEndOf="@+id/video_content"
app:layout_constraintStart_toStartOf="@+id/video_content"
app:layout_constraintTop_toTopOf="@+id/video_content" />
</android.support.constraint.ConstraintLayout>
直接调用
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<com.zuji.entrance.widget.MainPageVideoView
android:id="@+id/video_main_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</android.support.constraint.ConstraintLayout>
解决播放黑屏:
要解决这个问题,需要等到视频真正开始渲染后再去掉VideoView 的背景。最终的解决办法是在onPrepared回调中,加添加一个setOnInfoListener的监听,在这个监听中将VideoView的背景清除。具体修改如下:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
videoView.setBackgroundColor(Color.TRANSPARENT);
return true;
}
});
这段代码的关键是MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START这个变量,Android SDK中给出的注释是:这个状态表示展现了用于渲染的第一帧视频,也就是这个时候才真正将视频帧展示到了屏幕上。
然而,这个变量是在4.1版本才引入的,4.1之前的版本依然不支持。4.1之前的版本,只能暂时通过方法三来优化。