Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

YouTubePlayerSupportFragment in a single-Activity app with orientation change

I tried to solve this problem, searched through the Internet, no real answer was found.

I'm developing an app where the YouTube player is needed. This player is the YouTubePlayerSupportFragment since it's in a support fragment (so it's also nested). After the initial setup I realized that whenever I rotate the phone, the video stops playing and it has to be restarted again. This is obviously not what I want.

Then I found some SO answers (like this) where people say that the Activity needs to handle the config changes, so I added android:configChanges="keyboardHidden|orientation|screenSize" to the Activity in the manifest. This solved the problem, the video now keeps playing even on orientation change and the full-screen rotation doesn't look ugly. Cool, I said, only to realize that this messed up big time the other parts of the app because the config is now being updated after all the views are in place. This means that if my phone was in portrait mode and I rotated it to landscape, the layout being used was still going to be the portrait one.

I found solutions for this suggesting calling setContentView(...) in the Activity's onConfigurationChanged(...) and reinflating the view in the Fragments, but this seems to be a rather cumbersome if not terrible solution as It's not just a simple content setting I need, the fragments need to be retained (e.g. scroll position in RecyclerView) too. The built-in setRetainInstance(true) does not work in this case as the view would be recreated with that either, but the config is still the old one when the onCreateView(...) is being called.

It would be nice if I could catch the configChanges events if the user is on that screen (fragment) only but retain Activity recreation anywhere else.

Don't suggest using more Activities, I cannot use a separate Activity for this screen and the rest of the app because of UI/UX reasons.

like image 278
Gergely Kőrössy Avatar asked Jul 14 '16 00:07

Gergely Kőrössy


1 Answers

As per this YouTube Android Player API Guidelines

It is encouraged that you handle configuration changes caused by orientation in your activity manually, to avoid recreating this fragment's view every time the configuration changes. For the best user experience, you should also manually handle the fullscreen event by changing the layout of your activity.(See the second approch)

As you are already handling on configuration change on your own, I can see two possible solutions of your problem.

  1. Set setFullscreenControlFlags (To your YouTubePlayer object) to FULLSCREEN_FLAG_ALWAYS_FULLSCREEN_IN_LANDSCAPE (This will causes the player to automatically enter fullscreen whenever the device enters landscape orientation.) in conjunction with FULLSCREEN_FLAG_CONTROL_ORIENTATION(To enable automatic control of the orientation.) flag.

Note that this flag should only be set if your activity is locked in portrait (and is specified as such in the manifest).

The flag is useful if you don't have a landscape layout for your activity, but would like to enable landscape orientation solely for fullscreen video watching.

  1. This approach might solve your problem and it is also suggested by official documentation as I mentioned above. In setFullscreenControlFlags method set FULLSCREEN_FLAG_CUSTOM_LAYOUT, that disables the default fullscreen layout handler, enabling you to control the transition to fullscreen layout manually. As well as enabling you to implement a custom fullscreen layout, this option also provides the advantage of avoiding the rebuffering that occurs in the default fullscreen behavior.

An application implementing custom fullscreen behavior should ensure two things

That the player's view takes up the whole available space of application's window whenever onFullscreen(boolean) is called. That the activity is not recreated when the orientation changes to landscape. To achieve this for an activity that supports portrait, you need to specify that your activity handles some configuration changes on its own in your application's manifest, including orientation, keyboardHidden and screenSize.

See here on how to use this flag.

As per the first link I shared, this second approach will avoid recreating fragment's view every time the configuration changes. Also you don't need to call setContentView(...) in onConfigurationChanged(...).

Hope this will help you.

like image 124
Pravin Divraniya Avatar answered Nov 09 '22 07:11

Pravin Divraniya