WindowInsetsControllerCompat使用 - SheTieJun/BaseKit GitHub Wiki

WindowInsetsControllerCompat

WindowInsetsControllerCompat使用 这里讲到的是:

WindowInsetsCompat.Type.ime() //键盘
WindowInsetsCompat.Type.statusBars() //状态栏
WindowInsetsCompat.Type.navigationBars() //导航栏
WindowInsetsCompat.Type.systemBars()  //状态栏、导航栏和标题栏

基于androidx.core:core-ktx:1.8.0

一、状态栏、导航栏相关

1. 沉浸式设置

  WindowCompat.setDecorFitsSystemWindows(window, false)

第二参数decorFitsSystemWindows表示是否沉浸,false 表示沉浸,true表示不沉浸

示例:

  //关键代码,沉浸
  WindowCompat.setDecorFitsSystemWindows(window, false)
  
  //设置专栏栏和导航栏的底色,透明
  window.statusBarColor = Color.TRANSPARENT
  window.navigationBarColor = Color.TRANSPARENT
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
       window.navigationBarDividerColor = Color.TRANSPARENT
  }
  
  //设置沉浸后专栏栏和导航字体的颜色,
  WindowCompat.getInsetsController(window,findViewById(android.R.id.content)).let { controller ->
                controller.isAppearanceLightStatusBars = isBlack
                controller.isAppearanceLightNavigationBars = isBlack
  }
  

2. 全屏

WindowInsetsCompat.Type.systemBars() 表示状态栏、导航栏和标题栏

 fun Activity.hideSystemUI() {
     WindowCompat.setDecorFitsSystemWindows(window, false)
     WindowCompat.getInsetsController(window,findViewById(android.R.id.content)).let { controller ->
         controller.hide(WindowInsetsCompat.Type.systemBars())
         controller.systemBarsBehavior =
               WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
     }
}

3. 退出全屏

  fun Activity.showSystemUI() {
      WindowCompat.setDecorFitsSystemWindows(window, true)			 
       WindowCompat.getInsetsController(window,findViewById(android.R.id.content)).show(WindowInsetsCompat.Type.systemBars())
 }

4.其他

val Activity.windowInsetsController: WindowInsetsControllerCompat
    get() = WindowCompat.getInsetsController(window, findViewById(android.R.id.content))

状态栏和标题栏都是可以单独控制的

  1. 显示状态栏,字体黑色
 window.statusBarColor = Color.TRANSPARENT //设置底色
 windowInsetsController?.let { controller ->
         controller.show(WindowInsetsCompat.Type.statusBars())
          controller.isAppearanceLightStatusBars = true//true字体黑色,false白色
}
  1. 关闭状态栏
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
  1. 显示导航栏
windowInsetsController.let { controller ->
         controller.show(WindowInsetsCompat.Type.navigationBars())
         controller.isAppearanceLightNavigationBars = true//true黑色,false白色
   }
  1. 隐藏导航栏
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())

二、键盘操作

1. 使用方式

   @JvmStatic
   fun hideSoftKeyboard(activity: Activity) {
      windowInsetsController.hide(WindowInsetsCompat.Type.ime())
    }

    @JvmStatic
    fun showSoftKeyboard(activity: Activity) {
    windowInsetsController.show(WindowInsetsCompat.Type.ime())
     }

2. 存在的问题

只在dialogfragment好像好像调用上面的打开键盘的方法没有效果

所以当需要配合EditText打开的时候还是用老的方法

  @JvmStatic
  fun focusEditShowKeyBoard(editText: EditText) {
            editText.isEnabled = true
            editText.isFocusable = true
            editText.isFocusableInTouchMode = true
            editText.requestFocus()
            val inputManager = editText.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            editText.setSelection(editText.text.length)
            inputManager.showSoftInput(editText, 0)
  }

其他

val Activity.windowInsets: WindowInsetsCompat?
    get() = ViewCompat.getRootWindowInsets(findViewById(android.R.id.content))

val Activity.windowInsetsController: WindowInsetsControllerCompat
    get() = WindowCompat.getInsetsController(window, findViewById(android.R.id.content))


/**
 * 是否具有 hasNavigationBars()
 */
fun FragmentActivity.hasNavigationBars(): Boolean {
    val windowInsetsCompat = windowInsetsCompat ?: return false
    return windowInsetsCompat.isVisible(Type.navigationBars())
            && windowInsetsCompat.getInsets(Type.navigationBars()).bottom > 0
}

/**
 * 获取NavigationBarsHeight
 */
fun FragmentActivity.getNavigationBarsHeight(): Int {
    val windowInsetsCompat = windowInsetsCompat ?: return 0
    return windowInsetsCompat.getInsets(Type.navigationBars()).bottom
}

/**
 * 获取StatusBarsHeight
 */
fun FragmentActivity.getStatusBarsHeight(): Int {
    val windowInsetsCompat = windowInsetsCompat ?: return 0
    return windowInsetsCompat.getInsets(Type.statusBars()).top
}

/**
 * 隐藏导航栏
 */
fun FragmentActivity.hideNavigationBars() {
    windowInsetsController.let { controller ->
        controller.hide(Type.navigationBars())
        controller.systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }
}

/**
 * 全屏
 * {@see [theme:EdgeStyle]} 填充刘海屏幕
 */
fun Activity.hideSystemUI() {
    //decorFitsSystemWindows 表示是否沉浸,false 表示沉浸,true表示不沉浸
    WindowCompat.setDecorFitsSystemWindows(window, false)
   windowInsetsController.let { controller ->
        controller.hide(Type.systemBars())
        controller.systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }
}

/**
 * 展示系统UI:状态栏和导航栏
 */
fun Activity.showSystemUI() {
    WindowCompat.setDecorFitsSystemWindows(window, true)
    windowInsetsController.show(Type.systemBars())
}

/**
 * 不沉侵,只修改状态栏的颜色
 */
fun Activity.setAppearance(
    isBlack: Boolean,
    @ColorInt color: Int = Color.TRANSPARENT
) {
    updateSystemUIColor(color)
    windowInsetsController.let { controller ->
        controller.isAppearanceLightStatusBars = isBlack
        controller.isAppearanceLightNavigationBars = isBlack
    }
}

/**
 * 修改状态栏、底部的导航栏的颜色
 */
fun Activity.updateSystemUIColor(@ColorInt color: Int = Color.TRANSPARENT) {
    window.statusBarColor = color
    window.navigationBarColor = color
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        window.navigationBarDividerColor = color
    }
}