laobie / StatusBarUtil

A util for setting status bar style on Android App.
http://t.cn/Rq746Kb
Apache License 2.0
8.82k stars 1.72k forks source link

配合BGASwipeBackLayout-Android 使用视频播放全屏问题的看这里 #166

Open ghost opened 6 years ago

ghost commented 6 years ago

自己踩的坑,贴出来给需要的兄弟参考 一般配合BGASwipeBackLayout 我们会使用这个方法设置statusbar颜色

 public void setStatusBarColor(@ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
        StatusBarUtil.setColorForSwipeBack(this, color, statusBarAlpha);
    }

不全屏的时候没问题,但是全屏之后你会发现,什么鬼,上面居然有一条东东横在那,可是明明statusbar已经隐藏了,这东西是什么鬼,于是开始翻看issues,又发现了一个方法,于是尝试

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE || newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_USER) {
                 //隐藏掉虚拟的模仿view
                 StatusBarUtil.hideFakeStatusBarView(this);
        } else if (newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimary));
        }
    }

看看hideFakeStatusBarView 做了什么

/**
     * 隐藏伪状态栏 View
     *
     * @param activity 调用的 Activity
     */
    public static void hideFakeStatusBarView(Activity activity) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            fakeStatusBarView.setVisibility(View.GONE);
        }
        View fakeTranslucentView = decorView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
        if (fakeTranslucentView != null) {
            fakeTranslucentView.setVisibility(View.GONE);
        }
    }

没啥毛病呀,可是发现这东西,依然存在,人家可以,为啥我的不可以???无奈只能查看源码,好在源码少,不复杂,于是乎看到了

    /**
     * 为滑动返回界面设置状态栏颜色
     *
     * @param activity       需要设置的activity
     * @param color          状态栏颜色值
     * @param statusBarAlpha 状态栏透明度
     */
    public static void setColorForSwipeBack(Activity activity, @ColorInt int color,
        @IntRange(from = 0, to = 255) int statusBarAlpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

            ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
            View rootView = contentView.getChildAt(0);
            int statusBarHeight = getStatusBarHeight(activity);
            if (rootView != null && rootView instanceof CoordinatorLayout) {
                final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                    coordinatorLayout.setFitsSystemWindows(false);
                    contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
                    boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
                    if (isNeedRequestLayout) {
                        contentView.setPadding(0, statusBarHeight, 0, 0);
                        coordinatorLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                coordinatorLayout.requestLayout();
                            }
                        });
                    }
                } else {
                    coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
                }
            } else {
                ///问题出在这了呀 ,padding 了一个statusBarHeight
                contentView.setPadding(0, statusBarHeight, 0, 0);
                contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
            }
            setTransparentForWindow(activity);
        }
    }

问题就出在contentView.setPadding(0, statusBarHeight, 0, 0); 这里并不是像setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) 中decorView.addView(createStatusBarView(activity, color, statusBarAlpha));所以为什么我们的方法StatusBarUtil.hideFakeStatusBarView(this);木有效果。。。 解决办法: 先看我的视频全屏方式(仅供参考):

protected void goFullScreen() {
        isFullScreen = true;
        fullScreenImageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.discover_video_fs_exit_fullscr));
        setUiFlags(true);
        //hideSystemUI();
        ActivityUtils.setRequestedOrientation(getContext(), ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        ViewGroup viewGroup = ActivityUtils.getWindow(getContext()).getDecorView().findViewById(android.R.id.content);
        //就是这里了,重新设置padding为0即可
        viewGroup.setPadding(0, 0, 0, 0);
        parentViewGroup = (ViewGroup) videoView.getParent();
        parentViewGroup.removeView(videoView);
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        viewGroup.addView(videoView, lp);

        RelativeLayout parent = (RelativeLayout) controlsContainer.getParent();
        ViewGroup.LayoutParams layoutParams = parent.getLayoutParams();
        layoutParams.width = getWidth() + 1000;
        parent.setLayoutParams(layoutParams);
    }

关键就在于viewGroup.setPadding(0, 0, 0, 0); 重新设置padding,当然旋转回来了别忘记重新设置statusbar,运行。。。完美了

kennir commented 6 years ago

多谢@techGay的线索,省掉不少时间 🙏 如果不想改播放器的代码可以直接在hide后重新设置一下padding

    /**
     * 隐藏状态栏
     * StatusBarUtil.hideFakeStatusBarView 会设置内边距
     * @see https://github.com/laobie/StatusBarUtil/issues/166
     */
    fun hideStatusBar() {
        StatusBarUtil.hideFakeStatusBarView(this)
        (findViewById(android.R.id.content) as? ViewGroup)?.setPadding(0, 0, 0, 0)
    }