I've got an activity extending AppCompatActivity
, using a theme extending Theme.AppCompat.Light.DarkActionBar
.
This activity's view is a LinearLayout
with a VERTICAL
orientation containing the following views:
A
FrameLayout
containing aYouTubePlayerSupportFragment
. Note that I'm calling the following methods on the obtainedYouTubePlayer
on initialization success:setPlayerStyle(PlayerStyle.CHROMELESS) addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT)
I also set an
onClickListener
on the player view, supposed to hide and show theActionBar
on demand.Another view containing video details and stuff
- Some bottom view
Note that the activity calls supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
and that the LinearLayout
has a top padding of android.support.v7.appcompat.R.attr.actionBarSize
.
In the AndroidManifest.xml
, the activity has android:configChanges="orientation|screenSize"
set.
In the activity's onConfigurationChanged
method, I'm checking for the screen orientation. If it's landscape, I'm "going fullscreen", if it's portrait, I'm going back to the normal layout.
By "going fullscreen", I mean:
- Setting view n°2 and view n°3
visibility
toView.GONE
- Setting the activity's
supportActionBar
background color to some transparent color like0x55000000
- Setting
getWindow().getDecorView().systemUiVisibility
toView.SYSTEM_UI_FLAG_FULLSCREEN
- Changing the view n°1
LayoutParams
, setting bothwidth
andheight
toMATCH_PARENT
- Calling
setFullscreen(true)
on theYouTubePlayer
Now when I'm in my app, everything works in portrait mode: the video plays, the player is correctly placed just below the ActionBar
. It continues to work as expected when going into landscape mode: everything disappears except the player (even the ActionBar
). Then I click on the now fullscreen YouTube Player.
The expected result would be that the ActionBar
shows up, without interrupting the playback.
The actual result is that both the system status bar and the ActionBar shows up, and the playback is interrupted with the following error:
YouTube video playback stopped due to unauthorized overlay on top of player. The YouTubePlayerView is obscured by android.support.v7.widget.ActionBarContainer{43744840 V.ED.... ........ 0,50-1280,162 #7f0d005b app:id/action_bar_container}. The view is inside the YouTubePlayerView, with the distance in px between each edge of the obscuring view and the YouTubePlayerView being: left: 0, top: 50, right: 0, bottom: 558..
The YouTubePlayer is supposed to let an ActionBar overlay it, as shown in the Overlay ActionBar Demo found in the Sample Applications. So what's the problem here? I thought it was just checking for the view covering it being an ActionBar or not, so I don't understand how this exact error is even possible!
Ok, so as there is really no support for the Android YouTube Player API, I'll answer with how you actually have to do it for it to work.
First, drop the idea of using the ActionBar. It's an old API, it's ugly to have the controls in it, it's a pain to handle and it doesn't even work if you're not using the sample given by Google. The rest of this answer will explain a working method on how to add controls on top of the YouTube Player, but if you really want to use the ActionBar, you will not find an answer here (nor anywhere else as far as I know).
Fine. Now, for this to work you can use the YouTube Player normally. I recommend using the Fragment, as having to extend an existing Activity class can be a problem. Remove all controls of the Player using player.setPlayerStyle(PlayerStyle.CHROMELESS)
in the OnInitializationSuccess
callback.
Now, to get your controls on top of the Player without it pausing, you need to use a DialogFragment
(Using a Dialog
alone may work, but again here using the Fragment brings more controls on what you can do):
- Create your own subclass of
DialogFragment
- Override
onCreate(Bundle)
and callsetStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar)
- Override
onCreateView(LayoutInflater, ViewGroup, Bundle)
and recreate your Activity layout here, however you want. I'm using Kotlin and Anko, so everything is dynamic for me, I have no XML. Anyway, recreate your Layout but without the final views (the result should be entirely invisible). - Now, in the view which replaces your player, let's say you used a
FrameLayout
, you can add your controls like if it was the Player'sFrameLayout
Override
onStart()
and call the following methods on the now createdDialog
, to make sure your Dialog is fullscreen and transparent:Dialog dialog = getDialog(); dialog.setCanceledOnTouchOutside(false); dialog.setCancelable(false); dialog.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { // TODO Dismiss the Dialog AND call onBackPressed() on the underlying Activity return true; } else { return false; } } }); Window window = getWindow(); window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.setDimAmount(0f); layoutParams.setFlags(layoutParams.getFlags() | WindowManager.LayoutParams.FLAG_DIM_BEHIND); window.setAttributes(layoutParams);
Now you'll have to handle your controls, make them disappear after a timer, etc. Just make sure that you put everything that will cover the Player at some point inside the Dialog(Fragment).
I'm not sure that everything I listed here is mandatory for this to work, but that's how I did it and it works.
Note: As I said, I'm working with Kotlin and Anko, I didn't write Java for some months now, so any code presented here may have small typos. Please just tell me if you see any error.
Bonus: How I handled Fullscreen.
To handle fullscreen mode, I simply set the visibility of everything but the Player AND the matching view (a FrameLayout
for me) in the Dialog
to GONE
, the make sure that LayoutParams
' width and height of those two views are set to MATCH_PARENT
. To exit fullscreen, just set all views' visibility you changed back to VISIBLE
.
来源:https://stackoverflow.com/questions/33998568/actionbar-overlaying-youtubeplayersupportfragment-from-youtube-player-api