MediaController positioning over VideoView

Viewed 66567

I have a VideoView that takes up the top half of the Activity in portrait orientation with the bottom half of the screen showing some images and text. I am playing a rtsp video stream in the video view when the Activity starts. I have attached a MediaController to the VideoView via the following code:

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

When I tap the VideoView to bring up the MediaController on the screen I expected the playback controls to appear overlaying the bottom area of the VideoView (the bottom of the MediaController even with the bottom of the VideoView). Instead the MediaController pops up lower down on the screen, overlaying some of the graphics and text I have below the VideoView.

Are there some additional steps I need to take to get the MediaController to appear where I want it to on the screen?

10 Answers

I encounter the same problem recently, using setAnchorView(videoView) will set the controller fully under VideoView instead hovering on the bottom area of it. My VideoView is one third screen in upper area, so the controller end up covering whatever View under VideoView.

Below is the way I end up doing it without writing full-blown custom controller (only overriding onSizeChanged of MediaController to move anchor up) :

Use FrameLayout as an anchor for MediaContoller, wrap it up together with VideoView as 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 custom MediaController that will move FrameLayout up (with MediaController that is anchored to it will follow) when its size changed :

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 custom controller above in place of the standard one and then anchor it to the 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);                
}

I use this code to solve it.

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

to set the mediacontroller view to the position you want. Hope this help you.

Put your video view inside a linear layout

<RelativeLayout 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"
    tools:context="com.example.hp.videoplayer.MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <VideoView
            android:layout_width="300dp"
            android:layout_height="180dp"
            android:id="@+id/player"
            android:layout_marginTop="40dp"
            android:layout_centerHorizontal="true"/>

    </LinearLayout>

</RelativeLayout>

I did it by wrapping the VideoView inside a LinearView such that the LinearView has layout_width="match_parent" so that it always stretches to the extent of the screen but layout_height="wrap_content" so that the height of the linear view is always fixed to the height of the content. This way when the video plays the controls are always positioned with the VideoView.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".DisplayClipActivity">

    <VideoView android:id="@+id/episode_clip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

and the code for the Activity:

// create media controller
val mediaController = MediaController(this@DisplayClipActivity)
mediaController.setAnchorView(videoView)
mediaController.setMediaPlayer(videoView)

// video view
videoView.setVideoURI(uri)
videoView.setMediaController(mediaController)
videoView.start()

With java 8:

videoView.setOnPreparedListener(mediaPlayer ->
    mediaPlayer.setOnVideoSizeChangedListener(
        (player, width, height) -> {
            MediaController controller = new MediaController(YourActivity.this);
            videoView.setMediaController(controller);
            controller.setAnchorView(videoView);
        }
    )
);
Related