这里 Android SystemUI 主要是指ActionBar, 顶部的状态栏和底部的导航栏,图片壁纸和 RecentPanel 不在本文的谈论范围之内;
严格来说, ActionBar 不算是 SystemUI, 但是我们放在这里,因为它和状态栏,导航栏经常会一起设置使用。
在 API 16 之前
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// the status bar.
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
setContentView(R.layout.activity_main);
}
...
}
在 API 16 及其之后
View decorView = getWindow().getDecorView();
// Hide the status bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar();
actionBar.hide();
如果是像上面这样使用 UI Flag 来隐藏 ActionBar 的话,不要在 onCreat() 生命周期中使用,因为如果用户点击的 Home 键再回来,ActionBar 会再次显示出来。所以,应给在 onResume() 或者在 onWindowFoucsChanged() 中调用。
// 隐藏 StatusBar
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
这里的 SYSTEM_UI_FLAGY_FULLSCREEN, 并不是全屏的意思,仅仅只是隐藏状态栏而已。
透明的状态栏是 4.4(API 19)以上才加入的新特性。
我们可以通过设置 theme 方式来实现
在 values-v19/style.xml 中
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">falseitem>
<item name="android:windowTranslucentNavigation">trueitem>
style>
在 5.0 以上版本, values-v21/style.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">falseitem>
<item name="android:windowTranslucentNavigation">trueitem>
<item name="android:statusBarColor">@android:color/transparent
style>
然后在 Manifest.xml 文件中引用就可以了,可以是指定整个 App, 也可以是指定单个的 Activity.
private void transparent(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
View mChildView = mContentView.getChildAt(0);
if (mChildView != null) {
mChildView.setPadding(
mChildView.getPaddingLeft(),
0,
mChildView.getPaddingRight(),
mChildView.getPaddingBottom()
);
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(Color.TRANSPARENT); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
官方的文档, Boolean internal attribute to adjust view layout based on system windows such as the status bar . If true, adjust the padding of this view to leave space for the system windows, will only take effict if this view is in a non-embedded activity.
简单的说就是,如果我们在根布局设置 fitsSystemWindow=”true” 的话,会预留出空间,当我们的布局位于status bar 或者底部导航栏 之下的部分有交互时,可以设置为 true, 防止点击到 System UI 上面
这里有更好的总结
这是例子
<LinearLayout
android:id="@+id/activity_fist_system"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
ListView>
LinearLayout>
这是现实效果,我们可以看到 ActionBar 和 status bar 部分显示出来了
设置 SystemUIVisiblity 的方式
在任意一个已经显示在窗口上的控件调用 View.setSystemUiVisibility();
直接在窗口的 LayoutParams.systemUiVisibility 上进行设置并通过 WindowManager.updateViewLayout 方法使其生效
用于调整状态栏与导航栏的标记;
SYSTEM_UI_FLAG_LOW_PROFILE, 使得状态栏与导航栏进入低辨识读模式;
SYSTEM_UI_FLAG_HIDE_NAVIGATION, 隐藏导航栏。窗口在布局时的 ParentFrame、ContentFrame以及DisplayFrame 都会延伸到整个屏幕;
SYSTEM_UI_FLAG_FULLSCREEN, 隐藏状态栏。
影响状态栏和导航栏结果的标记
SYSTEM_UI_FLAG_LAYOUT_STABLE , 声明这个标记的窗口的 ContentFrame 不会随着导航栏或者状态栏的显示或隐藏而发生改变;
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION, PhoneWindowManager 在对声明了这个标记的窗口进行布局时会认为导航栏已经隐藏,无论导航栏是否真的被隐藏;
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN, PhoneWindowManager 在对声明了这个标记的窗口进行布局时会认为导航栏和状态栏都已经隐藏了,无论状态栏和导航栏是否真的被隐藏了。