之前写过一篇状态栏小记,这里加入虚拟按键重新做一下总结。
前言
Android 4.0之后,我们可以通过setSystemUiVisibility(int)方法,结合各种flag来设置系统组件(状态栏、虚拟按键)的显示或隐藏。那么有哪些Flag呢?Android官方文档有以下flag:
- View.SYSTEM_UI_FLAG_FULLSCREEN - View has requested to go into the normal fullscreen mode so that its content can take over the screen while still allowing the user to interact with the application. 
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - View has requested that the system navigation be temporarily hidden. 
- View.SYSTEM_UI_FLAG_IMMERSIVE - View would like to remain interactive when hiding the navigation bar with SYSTEM_UI_FLAG_HIDE_NAVIGATION. 
- View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - View would like to remain interactive when hiding the status bar with SYSTEM_UI_FLAG_FULLSCREEN and/or hiding the navigation bar with SYSTEM_UI_FLAG_HIDE_NAVIGATION. 
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - View would like its window to be laid out as if it has requested SYSTEM_UI_FLAG_FULLSCREEN, even if it currently hasn’t. 
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - View would like its window to be laid out as if it has requested SYSTEM_UI_FLAG_HIDE_NAVIGATION, even if it currently hasn’t. 
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE - When using other layout flags, we would like a stable view of the content insets given to fitSystemWindows(Rect). 
- SYSTEM_UI_FLAG_LIGHT_STATUS_BAR - Requests the status bar to draw in a mode that is compatible with light status bar backgrounds. 
- View.SYSTEM_UI_FLAG_LOW_PROFILE - View has requested the system UI to enter an unobtrusive “low profile” mode. 
- SYSTEM_UI_FLAG_VISIBLE - View has requested the system UI (status bar) to be visible (the default). 
- SYSTEM_UI_LAYOUT_FLAGS - Flags that can impact the layout in relation to system UI. 
实用代码
在做与状态栏、虚拟按键相关的工作时,有些代码亲测比较实用。
获取状态栏高度:
| 1 | /** | 
判断是否有虚拟按键:
| 1 | /** | 
获取虚拟按键的高度:
| 1 | /** | 
显示状态栏:
| 1 | WindowManager.LayoutParams attr = getWindow().getAttributes(); | 
隐藏状态栏:
| 1 | WindowManager.LayoutParams lp = getWindow().getAttributes(); | 
关于隐藏状态栏以及虚拟按键的显示、隐藏,目前知道的只有通过setSystemUiVisibility方法结合flag来实现。
隐藏虚拟按键:
| 1 | getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); | 
下面来做一个示例。
示例
前言中11种flag,真正用到的也就几种,下面结合示例来说。
新建一个应用,将Activity设置为全屏,并且横屏(模拟直播、播放视频类似的环境)。
先贴一下示例代码:
| 1 | public class MainActivity extends AppCompatActivity { | 
运行效果如下图:
- 可以看到,在我点击依次”Hello World”之后,button往下移了一点点,同时状态栏也显示了。(初始的时候虚拟按键就已经显示)
- 再点击一下,进行隐藏操作,状态栏、虚拟按键同时消失。当点击中间的button弹出dialog时,虚拟按键与状态栏会同时出来。然后关掉dialog后要连着点2次,状态栏、虚拟按键才会消失。
针对第一点,是初始的时候,虚拟按键在App布局之外,当执行SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN(根据说明:按全屏模式来表现,尽管当前没有设置全屏模式)之后,App布局占据手机整个显示框,所以会“变高”了些,button会下移。
针对第二点,目前也不知道是什么原因导致必须点2次才会执行消失操作。姑且以为是虚拟按键抢占焦点,第一次的点击被它消费了,第二次才是我们App进行消费。另外,当弹出dialog时,我们也可以控制状态栏不显示,将hideOperation改为如下:
| 1 | private void hideOperation() { | 
如此,当弹出dialog时,状态栏便不会显示了,但是虚拟按键是一定会显示的。可以认为:SYSTEM_UI_FLAG_FULLSCREEN flag的意思就是全屏显示,在此flag下,不会显示状态栏。
至于点击2次才消失的解决方案,便是取消onWindowFocusChanged中的注释,如此,1、2中描述的问题都不会出现了。
通过SYSTEM_UI_FLAG_HIDE_NAVIGATION来隐藏虚拟按键,会导致一个问题:界面有交互时虚拟按键会自动显示。要解决这个问题,便要用到SYSTEM_UI_FLAG_IMMERSIVE了,它的意思是当虚拟按键隐藏时仍然保留交互,可以理解为虚拟按键只是隐藏,但仍然还在,所以发生交互的时候便不会再自动显示了。
总结
- SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:按照全屏模式来显示,尽管当前没有设置为全屏模式,设置此flag便会抢占虚拟按键的空间,使应用真正的全屏,虚拟按键若要显示,则只是覆盖在应用的View上了。
- SYSTEM_UI_FLAG_FULLSCREEN:全屏显示,此模式下不会显示状态栏。
- SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键。
- SYSTEM_UI_FLAG_IMMERSIVE:当虚拟按键隐藏时,仍然保留交互。解决隐藏后界面发生交互又自动显示的问题。
- SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:按照隐藏虚拟按键模式显示,尽管当前没有设置为隐藏虚拟按键模式。针对示例中的第一点,将SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN改为此flag或者SYSTEM_UI_FLAG_HIDE_NAVIGATION都会使App充满显示框,导致button下移。
大致就说这些了,还有一些flag没弄明白,后面继续努力,写得有点乱~
