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

官网: 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.
       
}
   
}
});


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值