YoutubePlayer - 导航栏覆盖

YoutubePlayer - Navigation Bar Overlay

我在我的应用程序中使用 YoutubePlayerSupportFragment。我正在添加 YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT 标志。从 documentation 我知道我的播放器在退出全屏后不会重新缓冲,但现在我必须处理操作栏和导航栏。但是文档没有说明或指出我可以如何处理这些情况。

现在我面临的问题目前只发生在 Asus Nexus 7 OS 5.1.1 中。我还有 LG G2 D802 OS 4.4.2、Samsung Galaxy TAB GT P5113 OS 4.4.2 和 Samsung Galaxy Tab SM-T310 OS 4.2.2,它们不会抛出 Overlay错误。在日志猫中,我收到以下消息。

03-09 15:54:39.760  11203-11203/com.jadoo.jadooplus W/YouTubeAndroidPlayerAPI﹕ 
YouTube video playback stopped due to unauthorized overlay on top of player. 
The YouTubePlayerView is obscured by android.view.View{c067400 V.ED.... ........ 0,736-1280,800 #1020030 android:id/navigationBarBackground}.
Top edge 24 px above YouTubePlayerView's bottom edge. .

所以我知道问题是在导航栏中。导航栏覆盖在播放器之上。

我的问题是这些

我试过监听点击事件但是在全屏模式下我无法获得任何所以我在 Activity 中尝试 Overriding dispatchTouchEvent() 并且我自己获得了一个点击事件但是即使那样也不能帮助我及时摆脱导航栏(实际上是在时间之前)。

我还尝试通过 OnSystemUiVisibilityChangeListener 监听系统 UI 的更改并在那里隐藏导航栏(但再次隐藏导航栏可能还为时过早)。

我已经在 android 清单文件中设置了 android:theme="@style/Theme.AppCompat.NoActionBar",所以我真的不需要只隐藏导航栏 action/status 栏。

另外,如果有人能确认这是设备特定的问题,那将是一个很大的帮助。

这就是解决问题的方法(这仍然不是解决方案,但这是我能找到的最接近的解决方案)。

所以,我在YoutubePlayerSupportFragment(或YoutubePlayerFragment)的onInitializationSuccess中添加了一个OnSystemUiChangeListener

(View) getView().getParent().setOnSystemUiVisibilityChangeListener();

提供 OnSystemUiChangeListener 的实现对象。

像这样覆盖方法 onSystemUiVisibilityChange()

@Override
public void onSystemUiVisibilityChange(int visibility) {

    if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) {
        scheduleNavigationBarHide();
    }
    else if (visibility == View.SYSTEM_UI_FLAG_HIDE_NAVIGATION || visibility == View.SYSTEM_UI_FLAG_LOW_PROFILE
            || visibility == View.SYSTEM_UI_FLAG_FULLSCREEN) {
        if (navigationBarHandler != null) {
            navigationBarHandler.cancel();
            navigationBarHandler.purge();
            navigationBarHandler = null;
        }
    }
}

提供方法 scheduleNavigationBarHide() 的定义。

private void scheduleNavigationBarHide() {


    if (navigationBarHandler != null) {
        Log.d(TAG, "Canceling navigationBarHandler.");
        navigationBarHandler.cancel();
        navigationBarHandler.purge();
        navigationBarHandler = null;
    }

    if (mContext != null && mContext instanceof JadooTVActivity) {
        navigationBarHandler = new Timer();

        navigationBarHandler.schedule(new TimerTask() {
            public void run() {
                ((JadooTVActivity) mContext).runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        if (!isPlayerSqueezed) {
                            hideAsImmersiveNavigationBar(Config.context);
                        }
                        else {
                            Utils.showNavigationBar(Config.context);
                        }
                    }
                });
            }
        }, 500);
    }
}

最后 hideAsImmersiveNavigationBar() 正如您可能已经猜到的那样,这是通过让 Navigation Bar 暂时身临其境来实现的。方法如下

private void hideAsImmersiveNavigationBar(Activity activity) {

    if(activity != null)
    {   View decorView = activity.getWindow().getDecorView();

        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE;
        decorView.setSystemUiVisibility(uiOptions);
    }
}

稍后当播放器关闭时,您可能想带回 Navigation Bar。将 UI 标志更改为 int uiOptions = View.SYSTEM_UI_FLAG_VISIBLE | View.SYSTEM_UI_FLAG_FULLSCREEN;

最后一点免责声明:我提供了应用程序已经过测试的设备列表,我不知道这是否适用于所有设备。如果您确实发现问题持续存在的设备,请随时发表评论。此外,从 API 19 添加了沉浸式模式,因此该解决方案在此之前无法在任何设备上运行,但我只在一台设备上遇到过问题 运行 API 21。所有旧设备均有效出色地。另外 If/when Navigation Bar 停留了 1 秒,我们仍然得到覆盖错误。

在 youtube 全屏时将 activity 更改为全屏。

 void toggleFullScreen(boolean goFullScreen){   
    if(goFullScreen){
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    }else{ 
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    } 

    yourView.requestLayout(); 
}