这个问题实际上出现在更复杂的情况下,包括方向更改和纵向和横向的不同布局,但在它的最小版本中,问题是:
我们想在"正常"之间来回切换。和"全屏"布局,我E:
要从普通模式切换到全屏模式,我们正在使用:
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);
所以,从这个
我们首先"扩展"对此:
但是"萎缩"回不起作用:
所以,似乎虽然Activity只允许在系统UI内部绘制,但它仍然会认为"它应该为系统UI留出空间。
所以我的问题是:我的代码中应该SHRINK_FLAGS
应该是什么,或者我应该完全不同的做什么?
我们使用的AppCompatActivity
主题为Theme.AppCompat.Light.DarkActionBar
。
答案 0 :(得分:3)
似乎布局的根目录为android:fitsSystemWindows="true"
。由于某些原因,我不知道,fitsSystemWindows
在更改系统UI标记时效果不佳。幸运的是,这个问题有一个解决方法。
首先,无条件地设置扩展系统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的版本(Kitkat 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,它将通知系统它必须再次应用insets:
mFit = fit;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
requestApplyInsets();
} else {
requestFitSystemWindows();
}
现在,您可以调用setFit(false)
在系统用户界面和setFit(true)
后面制作视图布局,以使布局适合系统窗口。
您可以获取此布局here的源代码。