J'ai donc étendu onMeasure de VideoView pour adapter la vidéo à une vue en plein écran.
voici comment:
public void setVideoAspect(int w,int h){
wVideo=w;
hVideo=h;
onMeasure(w, h);
}
@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(wVideo!=0 && hVideo!=0)
setMeasuredDimension(wVideo,hVideo);
}
J'appelle setVideoAspect () avec les métriques d'affichage (largeur, hauteur) de l'écran. Le problème est que cette méthode étire la vidéo pour s’adapter à l’écran. Je veux pouvoir garder le rapport d'aspect. (J'ai une taille vidéo de 4: 3 et une taille d'écran de 3: 2.) J'ai utilisé le code suivant pour donner les mesures de rapport conservées à la vue:
int height = (int) (metrics.widthPixels*3/(float)4);
int width= metrics.widthPixels;
mVideoView.setVideoAspect(width,height);
Cela fait donc l'affaire mais il y a un problème: cela me donne une vidéo 4: 3 avec la largeur de l'écran et redimensionne correctement la hauteur, mais cela ne centre pas la vidéo. (Cela coupe juste la partie inférieure de la vidéo au lieu des haut et bas de la même manière.) J'ai une disposition relative contenant le VideoView avec la gravité du VideoView définie au centre.
Essayez plutôt d'utiliser FrameLayout
. Je ne sais pas pourquoi, mais si j'utilise une variable Linear
ou Relative
dans mon code, elle ne sera pas centrée, mais FrameLayout
le fera. Voici le code XML qui adapte ma vidéo à l'écran, en préservant le rapport et en le centrant:
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:background="@drawable/bg">
<!-- Video player -->
<VideoView
Android:id="@+id/surface_view"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:layout_gravity="center"/>
</FrameLayout>
Afin de centrer la vidéo dans RelativeLayout J'ai ajouté les deux layout_gravity="center"
et layout_centerInParent="true"
. Cela fonctionne sur mon téléphone Android 4.3.
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<VideoView Android:id="@+id/surface_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="center"
Android:layout_centerInParent="true" />
</RelativeLayout>
La réponse de Cameron de manière programmatique (au cas où quelqu'un comme moi en aurait besoin)
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
FrameLayout fl = new FrameLayout(this);
fl.setLayoutParams(lp);
VideoView vv = new VideoView(this);
FrameLayout.LayoutParams lp2 = new FrameLayout.LayoutParams(lp);
lp2.gravity = Gravity.CENTER;
vv.setLayoutParams(lp2);
fl.addView(vv);
setContentView(fl);
Cela fonctionne pour n'importe quelle vidéo en conservant le rapport hauteur/largeur de la vidéo. Il positionne la vidéo dans VideoView et effectue un recadrage au centre ou un centre à l'intérieur comme un ImageView.
J'utilise VideoView pour couvrir l'ensemble de ConstraintLayout. Vous pouvez utiliser n'importe quelle autre disposition probablement avec match_parent comme largeur et hauteur.
<?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/videoView"
Android:layout_width="0dp"
Android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</Android.support.constraint.ConstraintLayout>
Dans onCreate:
Uri uri = //The uri of your video.
VideoView videoView = findViewById(R.id.videoView);
videoView.setVideoURI(uri);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//Get your video's width and height
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
//Get VideoView's current width and height
int videoViewWidth = videoView.getWidth();
int videoViewHeight = videoView.getHeight();
float xScale = (float) videoViewWidth / videoWidth;
float yScale = (float) videoViewHeight / videoHeight;
//For Center Crop use the Math.max to calculate the scale
//float scale = Math.max(xScale, yScale);
//For Center Inside use the Math.min scale.
//I prefer Center Inside so I am using Math.min
float scale = Math.min(xScale, yScale);
float scaledWidth = scale * videoWidth;
float scaledHeight = scale * videoHeight;
//Set the new size for the VideoView based on the dimensions of the video
ViewGroup.LayoutParams layoutParams = videoView.getLayoutParams();
layoutParams.width = (int)scaledWidth;
layoutParams.height = (int)scaledHeight;
videoView.setLayoutParams(layoutParams);
}
});
J'espère que ça aide quelqu'un!