Posicionamiento de MediaController sobre VideoView

Tengo un VideoView que ocupa la mitad superior de la actividad en la orientación vertical con la mitad inferior de la pantalla que muestra algunas imágenes y texto. Estoy reproduciendo una secuencia de vídeo rtsp en la vista de vídeo cuando se inicia la Actividad. He adjuntado un MediaController al VideoView a través del siguiente código:

MediaController controller = new MediaController(this); controller.setAnchorView(this.videoView); controller.setMediaPlayer(this.videoView); this.videoView.setMediaController(controller); 

Cuando toco el VideoView para mostrar el MediaController en la pantalla, esperaba que los controles de reproducción aparecieran superpuestos al área inferior del VideoView (la parte inferior del MediaController incluso con la parte inferior del VideoView). En su lugar, el MediaController aparece más abajo en la pantalla, superponiendo algunos de los gráficos y el texto que tengo debajo de la VideoView.

¿Hay algunos pasos adicionales que necesito tomar para que el MediaController aparezca donde yo quiero que aparezca en la pantalla?

Francamente, acabo de escribir mi propio controlador. De hecho, lo hice una vez .

Dicho esto, intente setAnchorView() – por mi lectura del código fuente, el MediaController aparecerá en la parte inferior de lo que sea la vista de anclaje.

La configuración de la vista de anclaje sólo funcionará si se conoce el tamaño de la vista de vídeo – no se realizará al iniciar. Pero usted puede hacer algo como esto:

 video.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { /* * add media controller */ mc = new MediaController(YourActivity.this); video.setMediaController(mc); /* * and set its position on screen */ mc.setAnchorView(video); } }); } }); 

Me pareció una solución muy fácil.

Apenas envuelva el videoView en un FrameLayout entonces usted puede agregar el MediaController a ese FrameLayout del código, como esto:

  MediaController mc = new MediaController(context); videoView.setMediaController(mc); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.BOTTOM; mc.setLayoutParams(lp); ((ViewGroup) mc.getParent()).removeView(mc); ((FrameLayout) findViewById(R.id.videoViewWrapper)).addView(mc); 

EDIT: desde que publiqué esta respuesta me encontré con un montón de problemas con conseguir que ocultar y con el control de su tamaño, así que lo que acabé haciendo es que acaba de crear mi propio diseño con controles que podría animar y trabajar sin dolores de cabeza

Encontré el mismo problema recientemente, usar setAnchorView (videoView) fijará el regulador totalmente debajo de VideoView en lugar de otro que se cierne en el área inferior de él. Mi VideoView es una tercera pantalla en el área superior, por lo que el controlador acaba cubriendo cualquier vista en VideoView.

A continuación se muestra la forma en que termino haciéndolo sin escribir un controlador personalizado completo (solo sobreponiendo onSizeChanged de MediaController para mover el ancla hacia arriba):

Utilice FrameLayout como un ancla para MediaContoller, envuélvalo junto con VideoView como se muestra a continuación:

 <RelativeLayout android:id="@+id/videoLayout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.3" android:layout_gravity="center" android:background="#000000"> <VideoView android:id="@+id/videoView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" /> <FrameLayout android:id="@+id/controllerAnchor" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" /> </RelativeLayout> 

Cree Custom MediaController que moverá FrameLayout hacia arriba (con MediaController que está anclado a él seguirá) cuando su tamaño cambiado:

 public class MyMediaController extends MediaController { private FrameLayout anchorView; public MyMediaController(Context context, FrameLayout anchorView) { super(context); this.anchorView = anchorView; } @Override protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) { super.onSizeChanged(xNew, yNew, xOld, yOld); RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) anchorView.getLayoutParams(); lp.setMargins(0, 0, 0, yNew); anchorView.setLayoutParams(lp); anchorView.requestLayout(); } } 

Utilice el controlador personalizado arriba en lugar del estándar y luego anótelo al FrameLayout:

 protected void onCreate(Bundle savedInstanceState) { //... videoView = (VideoView) findViewById(R.id.videoView1); videoController = new MyMediaController(this, (FrameLayout) findViewById(R.id.controllerAnchor)); videoView.setMediaController(videoController); //... } public void onPrepared(MediaPlayer mp) { videoView.start(); FrameLayout controllerAnchor = (FrameLayout) findViewById(R.id.controllerAnchor); videoController.setAnchorView(controllerAnchor); } 

Utilizo este código para solucionarlo.

 mediaController.setPadding(0, 0, 0, px); 

Para establecer la vista del mediacontroller en la posición que desee. Espero que esto te ayude.

  //It work good with me <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <VideoView android:id="@+id/videoview" android:layout_width="640dp" android:layout_height="400dp" android:layout_centerInParent="true" > </VideoView> <FrameLayout android:id="@+id/videoViewWrapper" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" > </FrameLayout> </RelativeLayout> package com.example.videoview; import android.app.Activity; import android.content.res.Configuration; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnPreparedListener; import android.media.MediaPlayer.OnVideoSizeChangedListener; import android.os.Bundle; import android.os.Handler; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.MediaController; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import android.widget.Toast; import android.widget.VideoView; public class MainActivity extends Activity { // private String path = "http://clips.vorwaerts-gmbh.de/VfE_html5.mp4"; private String path = "http://2387227f13276d2e8940-fbe0b8d9df729a57ca0a851a69d15ebb.r55.cf1.rackcdn.com/hero_2012_demo.mp4"; private VideoView mVideoView; MediaController mc; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (mVideoView != null) return; /** * TODO: Set the path variable to a streaming video URL or a local media * file path. */ mVideoView = (VideoView) findViewById(R.id.videoview); mVideoView.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { Toast.makeText(MainActivity.this, "The End", Toast.LENGTH_LONG) .show(); } }); if (path == "") { // Tell the user to provide a media file URL/path. Toast.makeText( MainActivity.this, "Please edit MainActivity, and set path" + " variable to your media file URL/path", Toast.LENGTH_LONG).show(); } else { /* * Alternatively,for streaming media you can use * mVideoView.setVideoURI(Uri.parse(path)); */ mVideoView.setVideoPath(path); mVideoView .setMediaController(new MediaController(MainActivity.this)); mVideoView.requestFocus(); mVideoView.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { // TODO Auto-generated method stub mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { /* * add media controller */ mc = new MediaController(MainActivity.this); mVideoView.setMediaController(mc); /* * and set its position on screen */ mc.setAnchorView(mVideoView); ((ViewGroup) mc.getParent()).removeView(mc); ((FrameLayout) findViewById(R.id.videoViewWrapper)) .addView(mc); mc.setVisibility(View.INVISIBLE); } }); mVideoView.start(); } }); mVideoView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if (mc != null) { mc.setVisibility(View.VISIBLE); new Handler().postDelayed(new Runnable() { @Override public void run() { mc.setVisibility(View.INVISIBLE); } }, 2000); } return false; } }); } } private RelativeLayout.LayoutParams paramsNotFullscreen, paramsFullscreen; /** * handle with the configChanges attribute in your manifest */ @Override public void onConfigurationChanged(Configuration newConfig) { // TODO Auto-generated method stub super.onConfigurationChanged(newConfig); if (paramsFullscreen == null) { paramsNotFullscreen = (RelativeLayout.LayoutParams) mVideoView .getLayoutParams(); paramsFullscreen = new LayoutParams(paramsNotFullscreen); paramsFullscreen.setMargins(0, 0, 0, 0); paramsFullscreen.height = ViewGroup.LayoutParams.MATCH_PARENT; paramsFullscreen.width = ViewGroup.LayoutParams.MATCH_PARENT; paramsFullscreen.addRule(RelativeLayout.CENTER_IN_PARENT); paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_LEFT); paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_TOP); paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); } // To fullscreen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { mVideoView.setLayoutParams(paramsFullscreen); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { mVideoView.setLayoutParams(paramsNotFullscreen); } } @Override protected void onPause() { if (mVideoView.isPlaying()) { mVideoView.pause(); } super.onPause(); } @Override public void onBackPressed() { if (mVideoView != null) { mVideoView.stopPlayback(); } finish(); } } <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.videoview" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.videoview.MainActivity" android:configChanges="orientation|screenSize" android:label="@string/app_name" android:theme="@android:style/Theme.Dialog" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

Esta es la primera vez que contesto una pregunta en stackoverflow, sólo inserto un VideoView dentro de un FrameLayout con las mismas medidas de ambos. MediaController estará en la parte inferior de FrameLayout. Esto funcionó para mí:

Main_activity.XML:

  <FrameLayout android:id="@+id/frame_layout_video" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="400dp"> <VideoView android:id="@+id/video_select" android:layout_width="wrap_content" android:layout_height="400dp" android:adjustViewBounds="true" android:clickable="true" android:scaleType="centerCrop" /> </FrameLayout> 

MainActivity.java:

 @Override public void onClick(View v) { int i = v.getId(); if(i == R.id.select_video){ selectVideo(); } private void selectVideo(){ //this code is to get videos from gallery: Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); galleryIntent.addCategory(Intent.CATEGORY_OPENABLE); galleryIntent.setAction(Intent.ACTION_GET_CONTENT); galleryIntent.setType("video/*"); startActivityForResult(galleryIntent, GALLERY_REQUEST); MediaController mediaController = new MediaController(this); mediaController.setAnchorView(mVideo); //mVideo is the VideoView where I insert the video mVideo.setMediaController(mediaController); mVideo.pause(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case 1: if (resultCode == RESULT_OK) { mVideoUri = data.getData(); mVideo.setVideoURI(mVideoUri); mVideo.start(); } } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.