从YouTube Player API覆盖ActionP的YouTubePlayerSupportFragment [英] ActionBar overlaying YouTubePlayerSupportFragment from YouTube Player API
问题描述
我有一个扩展了AppCompatActivity
的活动,使用了扩展了Theme.AppCompat.Light.DarkActionBar
的主题.
此活动的视图是LinearLayout
且方向为VERTICAL
,其中包含以下视图:
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:
-
包含
YouTubePlayerSupportFragment
的FrameLayout
.请注意,初始化成功后,我将在获得的YouTubePlayer
上调用以下方法:
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)
我还在播放器视图上设置了onClickListener
,应该按需隐藏和显示ActionBar
.
I also set an onClickListener
on the player view, supposed to hide and show the ActionBar
on demand.
另一个包含视频详细信息和内容的视图
Another view containing video details and stuff
请注意,该活动调用supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
,并且LinearLayout
的顶部填充为android.support.v7.appcompat.R.attr.actionBarSize
.
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
.
在AndroidManifest.xml
中,活动设置为android:configChanges="orientation|screenSize"
.
在活动的onConfigurationChanged
方法中,我正在检查屏幕方向.如果是风景,则我要全屏";如果是人像,则要恢复到正常布局.
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.
全屏"是指:
- 将视图n°2和视图n°3设置为
visibility
至View.GONE
- 将活动的
supportActionBar
背景颜色设置为某些透明颜色,例如0x55000000
- 将
getWindow().getDecorView().systemUiVisibility
设置为View.SYSTEM_UI_FLAG_FULLSCREEN
- 更改视图n°1
LayoutParams
,将width
和height
都设置为MATCH_PARENT
- 在
YouTubePlayer
上调用
setFullscreen(true)
- 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
现在,当我进入应用程序时,所有内容都将以纵向模式运行:播放视频时,播放器正确放置在ActionBar
下方.进入横向模式时,它将继续按预期工作:除了播放器(甚至是ActionBar
)之外,其他所有内容都消失了.然后,我点击现在的全屏YouTube播放器.
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.
预期结果是ActionBar
出现,而不会中断播放.
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视频播放停止. YouTubePlayerView已被android.support.v7.widget.ActionBarContainer {43744840 V.ED .... ................. 0,50-1280,162#7f0d005b app:id/action_bar_container}遮盖.该视图位于YouTubePlayerView内,模糊视图的每个边缘与YouTubePlayerView之间的距离(以px为单位)为:左:0,上:50,右:0,下:558 ..
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..
YouTubePlayer应该让ActionBar覆盖它,如示例应用程序.那么这是什么问题呢?我以为它只是在检查是否涵盖了它是否为ActionBar的视图,所以我什至不知道这个确切的错误怎么可能!
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!
推荐答案
好吧,由于Android YouTube Player API确实不支持,因此我将回答您如何实际使用它.
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.
首先,放弃使用ActionBar的想法.这是一个旧的API,其中包含控件很丑陋,很难处理,如果您不使用Google提供的示例,它甚至不起作用.此答案的其余部分将说明如何在YouTube播放器顶部添加控件的有效方法,但是如果您确实要使用ActionBar,则无法在此处找到答案(在其他任何地方也无法找到答案)据我所知).
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).
好.现在,要使其正常工作,您可以正常使用YouTube播放器.我建议使用Fragment,因为必须扩展现有的Activity类可能是一个问题.在OnInitializationSuccess
回调中使用player.setPlayerStyle(PlayerStyle.CHROMELESS)
删除播放器的所有控件.
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.
现在,要在不暂停播放器的情况下将控件置于播放器顶部,您需要使用DialogFragment
(单独使用Dialog
可能会起作用,但是再次使用Fragment可以带来更多控件的信息) ):
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):
- 创建自己的
DialogFragment
子类
- 覆盖
onCreate(Bundle)
并致电setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar)
- 覆盖
onCreateView(LayoutInflater, ViewGroup, Bundle)
,然后根据需要在此处重新创建活动"布局.我正在使用Kotlin和Anko,所以一切对我来说都是动态的,我没有XML.无论如何,请重新创建您的版式,但不要保留最终视图(结果应完全不可见). - 现在,在替换播放器的视图中,假设您使用了
FrameLayout
,则可以添加控件,就像它是播放器的FrameLayout
-
覆盖
onStart()
并在现在创建的Dialog
上调用以下方法,以确保您的对话框是全屏且透明的:
- 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);
现在,您必须处理控件,使它们在计时器后消失,等等. 只要确保将所有可以覆盖播放器的东西都放在Dialog(Fragment)的某个位置即可.
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.
注意:正如我所说,我正在与Kotlin和Anko一起工作,几个月来我一直没有写Java,所以这里介绍的任何代码可能都有小错别字.请告诉我您是否遇到任何错误.
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.
奖金:我如何全屏显示.
要处理全屏模式,我只需将除播放器和匹配视图(对我来说是FrameLayout
)之外的所有内容设置为GONE
,请确保LayoutParams
的宽度和这两个视图的高度设置为MATCH_PARENT
.要退出全屏,只需将您更改为VISIBLE
的所有视图的可见性设置.
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
.
这篇关于从YouTube Player API覆盖ActionP的YouTubePlayerSupportFragment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!