控制窗口

 

重要的FLAG

焦点、触摸、输入事件类

  • FLAG_NOT_FOCUSABLE:设置后输入事件会略过这个窗口,传递到下个窗口;窗口范围内的触摸事件失效,范围外的会传递到下个窗口;这个窗口会置于软键盘之上,如果又设置FLAG_ALT_FOCUSABLE_IM则不会。
  • FLAG_NOT_TOUCH_MODAL:设置后,在窗口范围外的触摸事件会传递到下个窗口,如果还设置了FLAG_WATCH_OUTSIDE_TOUCH,那么还会在第一次DOWN时收到一个MotionEvent.OUT_SIDE事件。
  • FLAG_NOT_TOUCHABLE:设置后,不管触摸事件是否在这个窗口范围内,都不会被这个窗口消费,也不会传递到下个窗口。
  • FLAG_LOCAL_FOCUS_MODE:设置后,窗口不能接收到任何事件,只能用injectInputEvent()向它传递事件。
  • FLAG_IGNORE_CHEEK_PRESSES:设置后可以防止脸颊贴在手机上时造成误操作。

锁屏、屏幕亮度类

  • FLAG_TURN_SCREEN_ON:设置后当窗口弹出时会点亮屏幕。
  • FLAG_DISMISS_KEYGUARD:设置后当窗口弹出时会解锁没密码的keyguards。
  • FLAG_KEEP_SCREEN_ON:设置后只要这个窗口可见,就保持屏幕常亮。
  • FLAG_SHOW_WHEN_LOCKED:设置后窗口在锁屏时也会弹出,但不会点亮屏幕或解锁;配合FLAG_KEEP_SCREEN_ON可以点亮屏幕;配合FLAG_DISMISS_KEYGUARD可以解锁没密码的keyguards。
  • FLAG_ALLOW_LOCK_WHILE_SCREEN_ON:不设置会关闭锁屏计时。
  • FLAG_DIM_BEHIND:设置后会在窗口布局阶段,找到此窗口所在的TaskStack,启动Dimming动画。动画的目标值是PhoneWindowManager.dimAmount,可以调用PhoneWindowManager.setAmount()设置;动画的默认时长是TaskStack.DEFAULT_DIM_DURATION。

布局类

  • FLAG_LAYOUT_IN_SCREEN / FLAG_LAYOUT_INSET_DECOR:要一起使用;前者设置后窗口布局在StableFullScreen区域进行,但结果不一定是全屏;后者设置后可以避免此窗口与系统UI发生冲突。
  • FLAG_LAYOUT_IN_OVERSCAN:设置后窗口布局在Overscan区域进行。
  • FLAG_LAYOUT_NO_LIMITS:设置后窗口可以扩展到屏幕外。
  • FLAG_FULLSCREEN:设置后窗口是全屏的。
  • FLAG_FORCE_NOT_FULLSCREEN:忽略FLAG_FULLSCREEN。
  • FLAG_LAYOUT_ATTACHED_IN_DECOR:为子窗口设置后,子窗口布局在父窗口的Decor区域进行,避免覆盖系统UI。

系统UI类

  • FLAG_TRANSLUCENT_STATUS:设置后状态栏透明;窗口布局范围扩展到状态栏。
  • FLAG_TRANSLUCENT_NAVIGATION:设置后导航栏透明;窗口布局范围扩展到导航栏。
  • FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS:设置后,此窗口出现时,可以调用setStatusBarColor()设置状态栏颜色,调用setNavigationBarColor()设置导航栏颜色。

软键盘类

  • SOFT_INPUT_STATE_UNCHANGED:取上一个焦点窗口的设置。
  • SOFT_INPUT_STATE_HIDDEN:当窗口弹出时隐藏软键盘;比如跳转Activity会隐藏。
  • SOFT_INPUT_STATE_ALWAYS_HIDDEN:当窗口弹出或显示时隐藏软键盘;比如跳转Activity或后退到Activity都会隐藏。
  • SOFT_INPUT_STATE_VISIBLE:当窗口弹出时弹出软键盘;比如跳转Activity会弹出。
  • SOFT_INPUT_STATE_ALWAYS_VISIBLE:当窗口弹出或显示时弹出软键盘;比如跳转Activity或后退到Activity都会弹出。
  • SOFT_INPUT_IS_FORWARD_NAVIGATION:比如有两个Activity都需要显示软键盘,从第一个跳转到第二个时,软键盘不会先收起再弹出,就是因为系统自动设置了这个FLAG;当自建窗口时,也许需要手动设置它。
  • SOFT_INPUT_ADJUST_RESIZE:软键盘会把窗口顶上去。
  • SOFT_INPUT_ADJUST_PAN:软键盘不会把窗口顶上去,滚动窗口使当前焦点可见。
  • SOFT_INPUT_ADJUST_NOTHING:什么也不做,软键盘直接覆盖在窗口上。

其他

  • FLAG_SECURE:设置后此窗口不能被截屏。
  • FLAG_SCALED:设置后Surface的内容会经过缩放后显示到屏幕上,缩放比例取决于attrs.width/requestedWidth;requestedWidth是Surface的尺寸,由DecorView的尺寸 x mAttachInfo.mApplicationScale得到。
  • FLAG_SHOW_WALLPAPER:设置后此窗口的下面是壁纸。

重要的回调

Activity中:

  • onWindowAttributesChanged(WindowManager.LayoutParams):当窗口属性改变时被调用。
  • onContentChanged():在setContentView()/addContentView()后被调用。
  • onWindowFocusChanged():当窗口得到或失去焦点时被调用。
  • onAttachedToWindow():当DecorView添加到窗口上时被调用。
  • onDetachFromWindow():当DecorView从窗口上移除时被调用。

沉浸式状态栏

需要扩展应用窗口添加状态栏高度两步。

扩展应用窗口

SDK19~20
  • 在style.xml文件中创建Theme,设置android:windowTranslucentStatus属性为true;
  • 在代码中为WindowManager.LayoutParams添加FLAG_TRANSLUCENT_STATUS。
SDK21~最新
  • 在style.xml文件中创建Theme,设置android:windowDrawsSystemBarBackgrounds属性为true,设置android:statusBarColor属性为某个颜色(如果是透明将显示灰白);
  • 在代码中为WindowManager.LayoutParams添加FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;调用Window.setStatusBarColor()设置颜色(如果是透明将显示灰白)。
  • 调用View.setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN SYSTEM_UI_FLAG_LAYOUT_STABLE),使应用窗口扩展至状态栏,可以避免灰白。

添加状态栏高度

  • 根布局调用View.setFitsSystemWindows(true),或在布局文件中设置android:fitsSystemWindows=”true”;
  • 根布局添加padding,高度为getResources().getDimensionPixelSize(getResources().getIdentifier(“status_bar_height”, “dimen”, “android”))。