Android VideoView orientation change with buffered video Android VideoView orientation change with buffered video android android

Android VideoView orientation change with buffered video


EDIT: (June 2016)

This answer is very old (I think android 2.2/2.3) and probably is not as relevant as the other answers below! Look to them first unless you're dev-ing on legacy Android :)


I was able to narrow down the problem to the onMeasure function in the VideoView class. By creating a child class and overriding the onMeasure function, I was able to get the desired functionality.

public class VideoViewCustom extends VideoView {    private int mForceHeight = 0;    private int mForceWidth = 0;    public VideoViewCustom(Context context) {        super(context);    }    public VideoViewCustom(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public VideoViewCustom(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public void setDimensions(int w, int h) {        this.mForceHeight = h;        this.mForceWidth = w;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        Log.i("@@@@", "onMeasure");        setMeasuredDimension(mForceWidth, mForceHeight);    }}

Then inside my Activity I just did the following:

@Overridepublic void onConfigurationChanged(Configuration newConfig) {    super.onConfigurationChanged(newConfig);    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);        questionVideo.setDimensions(displayHeight, displayWidth);        questionVideo.getHolder().setFixedSize(displayHeight, displayWidth);    } else {        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);        questionVideo.setDimensions(displayWidth, smallHeight);        questionVideo.getHolder().setFixedSize(displayWidth, smallHeight);    }}

The line:

questionVideo.getHolder().setFixedSize(displayWidth, smallHeight);

is key in order to make this work. If you do the setDimensions call without this guy, the video still will not resize.

The only other thing you need to do is ensure that you call setDimensions() inside the onCreate() method as well or your video will not start buffering as the video won't be set to draw on a surface of any size.

// onCreate()questionVideo.setDimensions(initialWidth, initialHeight); 

One last key part - if you ever find yourself wondering why the VideoView isn't resizing on rotation, you need to ensure the dimensions you're resizing to are either exactly equal to the visible area or less than it. I had a really big problem where I was setting the VideoView's width/height to the entire display size when I still had the notification bar/title bar on the screen and it was not resizing the VideoView at all. Simply removing the notification bar and title bar fixed the problem.

Hopefully this helps someone in the future!


Here is a really easy way to accomplish what you want with minimal code:

AndroidManifest.xml:

android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"

Note: Edit as needed for your API, this covers 10+, but lower APIs require removing the "screenSize|screenLayout|uiMode" portion of this line

Inside the "OnCreate" method, usually under "super.onCreate", add:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,            WindowManager.LayoutParams.FLAG_FULLSCREEN);

And then somewhere, usually at the bottom, add:

@Overridepublic void onConfigurationChanged(Configuration newConfig) {    super.onConfigurationChanged(newConfig);    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,            WindowManager.LayoutParams.FLAG_FULLSCREEN);}

This will resize the video to fullscreen whenever the orientation has changed without interrupting playback and only requires overriding the configuration method.


First of all, thanks a lot for your own extensive answer.

I had the same problem, the video would most of the time be smaller, or bigger, or distorted inside the VideoView after a rotation.

I tried your solution, but I also tried random things, and by chance I noticed that if my VideoView is centered in its parent, it magically works by itself (no custom VideoView needed or anything).

To be more specific, with this layout, I reproduce the problem most of the time:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <VideoView        android:id="@+id/videoView"        android:layout_width="match_parent"        android:layout_height="match_parent" /></RelativeLayout>

With this one layout, I never have the problem (plus, the video is centered, which is how it should be anyway ;):

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <VideoView        android:id="@+id/videoView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerInParent="true" /></RelativeLayout>

It also works with wrap_content instead of match_parent (the video still takes all the space) which does not make much sense to me.

Anyway, I don't have any explanation for this - this looks like a VideoView bug to me.