Positioning MediaController over VideoView

I have a VideoView that takes up the top half of the Activity in portrait orientation, and the bottom half of the screen shows some images and text. When I start Activity, I play the rtsp video stream as a video. I connected MediaController to VideoView using the following code:

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

When I click VideoView to call the MediaController on the screen, I expected the playback controls to appear in the bottom area of ​​the VideoView (at the bottom of the MediaController even at the bottom of the VideoView). Instead, the MediaController appears on the screen from bottom to bottom, overlapping part of the graphics and text that I have below the VideoView.

Are there a few more steps I need to take to get MediaController to appear where I want it to appear on the screen?

+48
android
Sep 10 '10 at 17:15
source share
7 answers

Honestly, I would just write my own controller. In fact, I did it once .

In this case, try setAnchorView() - by reading the source code, MediaController will appear at the bottom of any kind of binding.

+5
Aug 12 '11 at 13:17
source share

Setting the snap view will work only if the size of the video image is known - it will not be set to init. But you can do something like this:

 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); } }); } }); 
+39
Sep 07 '12 at 11:25
source share

I found a very easy solution.

Just wrap the videoView in a FrameLayout, then you can add a MediaController to this FrameLayout from the code, for example:

  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: since I posted this answer, I ran into a lot of problems in getting it to hide and control its size, so I ended up doing this, I just created my own layout with controls that I could animate and work without headache

+14
Jul 02 '14 at 11:15
source share

I am facing the same problem recently, using setAnchorView (videoView), will fully install the controller under VideoView instead of hovering in the bottom area. My VideoView is one third screen in the upper area, so the controller ultimately covers any view in the VideoView.

The following is the way that I end up doing this without creating a full-blown user controller (only overriding onSizeChanged MediaController to move the anchor):

Use FrameLayout as a binding for MediaContoller, wrap it along with VideoView, as shown below:

 <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> 

Create your own MediaController that will move the FrameLayout up (with the MediaController attached to it when it changes):

 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(); } } 

Use the special controller above instead of the standard one, and then bind it to 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); } 
+11
Dec 04 '13 at 10:29
source share

I use this code to solve it.

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

to set the mediacontroller view to the desired position. Hope this helps you.

+7
Mar 05 '12 at 8:32
source share
  //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> 
+3
Nov 28 '14 at 6:42
source share

This is the first time I answer a question in stackoverflow, I only embed a VideoView inside FrameLayout with the same measures. MediaController will be at the bottom of the FrameLayout. This worked for me:

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(); } } } 
0
May 4 '17 at 1:18
source share



All Articles