android 状态栏和导航栏(status and navigation bars)

翻译 2015年11月17日 17:12:52
官网:http://developer.android.com/intl/zh-cn/training/system-ui/index.html
System Bars 包括:顶部的状态栏和底部的导航栏(status and navigation bars)
声明:调节 status and navigation bars 要求系统版本 >4.0。目前android 不支持=<4.0的版本。

隐藏 status and navigation bars
同过设置一个flag来实现: SYSTEM_UI_FLAG_LOW_PROFILE
// This example uses decor view, but you can use any visible view.
View decorView = getActivity().getWindow().getDecorView();
int uiOptions =View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView
.setSystemUiVisibility(uiOptions);
显示 status and navigation bars
View decorView = getActivity().getWindow().getDecorView();
// Calling setSystemUiVisibility() with a value of 0 clears
// all flags.
decorView
.setSystemUiVisibility(0);
当用户触摸到 status and navigation bars,flag会被清除,会使状态栏和导航栏显示。一旦flag被清除,若果你想再次隐藏,你需要重新设置。


隐藏状态栏
不同的android版本,隐藏的方法不尽相同。

1.隐藏状态栏(<=4.0版本)
通过设置主题的方法:
XML里设置:
<application
    ...
   
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen">
    ...
</application>

代码设置:
publicclassMainActivityextendsActivity{

   
@Override
   
protectedvoid onCreate(Bundle savedInstanceState){
       
super.onCreate(savedInstanceState);
       
// If the Android version is lower than Jellybean, use this call to hide
       
// the status bar.
       
if(Build.VERSION.SDK_INT <16){
            getWindow
().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                   
WindowManager.LayoutParams.FLAG_FULLSCREEN);
       
}
        setContentView
(R.layout.activity_main);
   
}
   
...
}

2.设置状态栏(>=4.1版本)
通过代码设置:
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被清除,如需隐藏,你需要重置。后面会介绍 UI Visibility Changes 对其进行监听。
· 你在哪里设置ui flag 有影响吗?如果你在 onCreate()方法中设置隐藏系统栏(状态栏和导航栏),那么当你按home键时,系统栏会重现。当你重回activity时,不会走onCreate()方法,所以系统栏不会隐藏。如果你想在重回activity时隐藏系统栏,请在onResume()或onWindowFocusChanged()方法中设置。
· 只有当 view在visible状态时,setSystemUiVisibility()才起作用。
· 导航栏离开view,会导致在setSystemUIVisibility()设置的flag被清除。

3.设置内容显示在状态栏后面

要求>=4.1版本。
设置flag
SYSTEM_UI_FLAG_LAYOUT_STABLE 来帮助你的应用保持一个稳定的布局.
当你使用这个方法,它会要求你确定在你应用的UI的关键部分(比如,一个地图应用的内置控件)不会被系统栏覆盖。否则,这会导致应用崩溃。在大多数情况下,你要处理这种情况,需要在在主题xml中设置<item name = "android:fitsSystemWindows">true</item>
这是用来调整填充的父viewGroup给系统窗口留下空间。对于大多数应用来说是充分的。

4. status bar 与 action bar 同步、衔接
要求>=4.1版本。
为了避免改变你的布局的大小,当action bar显示隐藏时,你可以给action bar 启动覆盖模式。在覆盖模式时,你的activity布局会充满所有可用空间,好像action bar 不在这里并且系统绘制action bar 在你的布局的前面。这样会遮盖上层的布局,但是当action bar 显示或隐藏时,系统不需要改变你的布局的大小,并且过渡是无缝的。
action bar 开启覆盖模式,你需要自定义theme继承已存在的theme.添加一项:
<item name = "android:windowActionBarOverlay">true</item>
然后,设置 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,如上描述,使你的activity布局用同样的可用的屏幕区域,当你已设置了SYSTEM_UI_FLAG_FULLSCREEN。当你想隐藏系统UI,用SYSTEM_UI_FLAG_FULLSCREEN。也会隐藏 action bar(因为windowActionBarOverlay=”true”)并且在隐藏和显示过程中伴有和谐的动画。

隐藏导航栏
导航栏是在android4.0(API level 14)引入的。

要求>=4.0版本。
通过设置flag :
View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
// a general rule, you should design your app to hide the status bar whenever you
// hide the navigation bar.
int uiOptions =View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
             
|View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView
.setSystemUiVisibility(uiOptions);
需要注意的是:
· 用这种方法,点击屏幕的任何地方都会引起系统栏(navigation and status bars)重现并保持可见。用户交互导致flags被清除。
· 一旦flags被清除,如果想重新隐藏,你需要重设flags。可通过UI Visibility Changes 监听变化。
· 你在哪里设置ui flag 有影响吗?如果你在 onCreate()方法中设置隐藏系统栏(状态栏和导航栏),那么当你按home键时,系统栏会重现。当你重回activity时,不会走onCreate()方法,所以系统栏不会隐藏。如果你想在重回activity时隐藏系统栏,请在onResume()或onWindowFocusChanged()方法中设置。
· 只有当 view在visible状态时,setSystemUiVisibility()才起作用。
· 导航栏离开view,会导致在setSystemUIVisibility()设置的flag被清除。

使内容出现在导航栏后面
要求版本>=4.1,你可以设置应用的内容出现在导航栏后面,这样,内容不会因为导航栏的显示或隐藏而改变大小。这样做需要使用SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION.你还需要使用SYSTEM_UI_FLAG_LAYOUT_STABLE来使你的应用保持布局平稳。
当你使用这个方法,它要求你确定你的app的ui的关键部分不会被系统bars覆盖。需要在在主题xml中设置<item name = "android:fitsSystemWindows">true</item>

侵入式全屏模式(重点应用方法)
android4.4引入一个新的flag:SYSTEM_UI_FLAG_IMMERSIVE 通过setSystemUiVisibility()设置,能让你的应用真的全屏。这个flag与SYSTEM_UI_FLAG_HIDE_NAVIGATION 和SYSTEM_UI_FLAG_FULLSCREEN 相比,隐藏系统栏并让应用捕获屏幕上的所有触摸事件。
当侵入式全屏模式被设置时,acitivity仍能接收所有触摸事件。用户通过在系统栏正常展现的地方向内滑动来显示系统栏。这回清除SYSTEM_UI_FLAG_HIDE_NAVIGATION flag(和SYSTEM_UI_FLAG_FULLSCREENflag,如果使用了),所以系统栏会显示。如果设置了View.OnSystemUiVisibilityChangeListener,这会触发监听。当然,如果你不想系统栏过一会又自动隐藏,可以使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag来代替。注意,“sticky”版本的flag不会触发监听,虽然系统栏会暂时显示在这个模式中。

1、非沉浸式模式。在进入沉浸式模式之前的显示。也是使用 IMMERSIVE flag的显示,用户滑动来显示系统栏,从而清除SYSTEM_UI_FLAG_HIDE_NAVIGATION 和SYSTEM_UI_FLAG_FULLSCREEN flags。一旦flag被清除,系统栏重现并持续显示。
注意,这是系统栏ui保持同步的最好方式。(这里说一句,实践过程中,你会发现,status bar 和 nevigation bar不断的隐藏显示过程中,可能会使二者是不同步,也就是说,一个是隐藏状态,一个是显示状态。)。所有和status bar一起显示的ui控件,一旦应用进入沉浸式模式,ui控件和system bar 一起隐藏。为了确保你的ui和system bar 同步显示,需要合适的使用View.OnSystemUiVisibilityChangeListener来观察变化。稍后会介绍。
2、提示气泡。当应用第一次进入沉浸模式时,会弹出提示气泡,提示你如果显示system bar.
3、沉浸式模式。应用进入沉浸模式,system bar 和其他ui控件都隐藏。可以用 IMMERSIVE 或 IMMERSIVE_STICKY.来达到这种状态。
4、sticky flag。用IMMERSIVE_STICKY flag会显示这种UI,用户滑动来显示system bar ,暂时出现半透明栏然后再次隐藏。滑动的行为不会清除任何flags,也不会触发System UI Visibility Change Listener。注意,记住,“immersive”flags只有在你同时使用SYSTEM_UI_FLAG_HIDE_NAVIGATION, 或SYSTEM_UI_FLAG_FULLSCREEN, 或都有。但是通常是status bar 和 nevigation bar 都隐藏,当你想设置成“全沉浸”模式时。

使用 Non-Sticky Immersion
// This snippet hides the system bars.
private void hideSystemUI() {
   
// Set the IMMERSIVE flag.
   
// Set the content to appear under the system bars so that the content
   
// doesn't resize when the system bars hide and show.
    mDecorView
.setSystemUiVisibility(
           
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
           
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
           
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
           
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
           
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
           
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}

// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
    mDecorView
.setSystemUiVisibility(
           
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
           
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
           
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

使用 Sticky Immersion

@Override
public void onWindowFocusChanged(boolean hasFocus) {
       
super.onWindowFocusChanged(hasFocus);
   
if (hasFocus) {
        decorView
.setSystemUiVisibility(
               
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
               
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
               
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
               
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
               
| View.SYSTEM_UI_FLAG_FULLSCREEN
               
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}

响应UI Visibility Changes

View decorView = getWindow().getDecorView();
decorView
.setOnSystemUiVisibilityChangeListener
       
(new View.OnSystemUiVisibilityChangeListener() {
   
@Override
   
public void onSystemUiVisibilityChange(int visibility) {
       
// Note that system bars will only be "visible" if none of the
       
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
       
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
           
// TODO: The system bars are visible. Make any desired
           
// adjustments to your UI, such as showing the action bar or
           
// other navigational controls.
       
} else {
           
// TODO: The system bars are NOT visible. Make any desired
           
// adjustments to your UI, such as hiding the action bar or
           
// other navigational controls.
       
}
   
}
});


Android 4.4之后状态栏和导航栏细节美化(沉浸式状态栏)

转载请注明出处:http://blog.csdn.net/demokui/article/details/54603284本篇文章出自:【姜奎的博客】1. 简介其实标题我是打算叫“抢眼的沉浸式状态栏”...
  • DemoKui
  • DemoKui
  • 2017年01月18日 17:46
  • 2383

Android动态控制状态栏以及系统导航栏显示和隐藏

其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发起的。因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法。而有些人...
  • Maiduoudo
  • Maiduoudo
  • 2017年08月16日 12:17
  • 1727

Android (争取做到)最全的底部导航栏实现方法

本文(争取做到)Android 最全的底部导航栏实现方法.
  • alcoholdi
  • alcoholdi
  • 2016年06月06日 11:08
  • 31900

Android底部导航栏的四种实现

现在大多数App都会用到底部导航栏,比如常见的聊天工具QQ、微信,购物App等等,有了底部导航栏,用户可以随时切换界面,查看不同的内容。它的实现方式也很多,以前大多使用TabHost来实现,但是现在我...
  • jxq1994
  • jxq1994
  • 2016年09月18日 13:10
  • 53065

Android 将App的内容延伸到状态栏/导航栏

看过Android的桌面应用都是介样的: 如何让自己的应用也达到这般效果呢?这里就介绍几种常用的方法以及它们之间的区别。首先展示下此次demo的布局和初始状态: ...
  • dahaohan
  • dahaohan
  • 2016年08月12日 15:48
  • 4915

Android界面编程——导航栏及菜单(六)

Android界面编程——导航栏及菜单 2.7导航栏及菜单 2.7.1  ActionBar ActionBar是Android3.0(API 11)开始增加的新特性,ActionBar出现在活动窗...
  • zhangyufeng0126
  • zhangyufeng0126
  • 2016年07月13日 16:40
  • 3411

Android学习之BottomNavigationBar实现Android特色底部导航栏

Android底部导航栏的实现方式特别多,例如TabHost,TabLayout,或者TextView等,都可以实现底部导航栏的效果,但是却没有Google官方统一的导航栏样式,今天讲的就是Googl...
  • qq_16131393
  • qq_16131393
  • 2016年05月15日 22:42
  • 29218

Android 最简单的导航栏实现

在开发中,我们经常碰到这样的控件,用来切换不同的Fragment 这种控件的实现的效果有多种多样,一般来说我们都是使用一个LinearLayout嵌套几个Button来实现,然后通过for循环来实现...
  • qwe511455842
  • qwe511455842
  • 2015年12月17日 21:31
  • 3201

Android动态导航栏的代码实现

  • 2017年08月06日 02:24
  • 80KB
  • 下载

Android 底部导航栏 BottomNavigationBar

大部分app,都采用导航栏的方式,无论是顶部导航栏还是底部导航栏,这是一个app的根骨,本文是采用Google最近添加到Material design中的底部导航栏BottomNavigationBa...
  • QQ55214
  • QQ55214
  • 2016年11月11日 11:12
  • 5790
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 状态栏和导航栏(status and navigation bars)
举报原因:
原因补充:

(最多只允许输入30个字)