3

这个问题实际上出现在更复杂的情况,涉及方位的变化和不同的纵向和横向的布局,但在它的最低版本的问题是这样的:如何从SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION恢复?

我们想来回切换之间的“正常”和“全屏“布局,我。 Ë:其中内容只占剩下的导航栏和状态栏

  • 一个布局,其中的内容导航和状态栏
  • 下占据了整个屏幕,幻灯片的内部空间

    • 一个布局

    ,从正常的切换,我们使用的是切换到全屏模式:

    public static final int EXPAND_FLAGS = View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
           | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
           | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; 
    
    getWindow().getDecorView().setSystemUiVisibility(EXPAND_FLAGS); 
    

    并切换回我们尝试:

    public static final int SHRINK_FLAGS = View.SYSTEM_UI_FLAG_VISIBLE; 
    
    getWindow().getDecorView().setSystemUiVisibility(SHRINK_FLAGS); 
    

    所以,从这个

    Layout after app start

    我们第一次 “扩大” 这样的:

    Layout after "expand" click

    但 “缩水” 后不工作:

    Layout after "expand" and "shrink"

    因此,虽然Activity只允许在系统UI中绘制,但它仍然“认为”它应该为系统UI留出空间。

    所以我的问题是:SHRINK_FLAGS应该在我的代码上面或应该做什么完全不同?

    我们使用AppCompatActivityTheme.AppCompat.Light.DarkActionBar主题。

    回答

    2

    似乎你的布局的根有android:fitsSystemWindows="true"。出于某种原因,我不知道,更改系统UI标志时,fitsSystemWindows无法正常工作。幸运的是,这个问题有一个解决方法。

    首先,设置扩展系统UI标志无条件地:

    getWindow().getDecorView().setSystemUiVisibility(
         View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
           | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
           | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
    ); 
    

    然后从布局的所有祖先视图中除去android:fitsSystemWindows="true"

    之后,创建一个布局,该布局将处理系统插入更改,并根据其属性的值添加或删除填充。这是最复杂的部分。根据平台版本的不同,您必须以不同的方式处理系统插入。对于低于20(奇巧Watch)的版本中,你必须重写View.fitSystemWindows()方法:

    @Override 
    protected boolean fitSystemWindows(final Rect insets) { 
        if (mFit) { 
         setPadding(insets.left, insets.top, insets.right, insets.bottom); 
         // Do not propagate the system insets further. 
         return true; 
        } else { 
         setPadding(0, 0, 0, 0); 
         // Do not consume the insets and allow other views handle them. 
         return false; 
        } 
    } 
    

    对于平台版本比20,你需要重写View.onApplyWindowInsets()法大于或等于和相同的处理,在前面的方法:

    @Override 
    public WindowInsets onApplyWindowInsets(final WindowInsets insets) { 
        if (mFit) { 
         setPadding(
           insets.getSystemWindowInsetLeft(), 
           insets.getSystemWindowInsetTop(), 
           insets.getSystemWindowInsetRight(), 
           insets.getSystemWindowInsetBottom() 
         ); 
         return insets.consumeSystemWindowInsets(); 
        } else { 
         setPadding(0, 0, 0, 0); 
         return insets; 
        } 
    } 
    

    最后创造了mFit领域的setter,它会通知它必须重新申请插图系统:

    mFit = fit; 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { 
        requestApplyInsets(); 
    } else { 
        requestFitSystemWindows(); 
    } 
    

    现在,您可以拨打setFit(false)将您的视图布局在系统UI和setFit(true)后面,以使布局适合系统窗口。

    你可以得到这个布局here的源代码。

    +0

    我不明白这是如何工作的,但你救了我的屁股,谢谢! –