在片段更改时恢复 Window 插入

Reverting Window Insets on fragment change

我有三个片段。我只想在一个片段上应用透明状态栏。为此,我在底部导航栏的 setOnItemSelectedListener 方法上调用了以下隐藏方法。还添加了我现在得到的图像

private fun hideStatusBar() {
    window.statusBarColor = ContextCompat.getColor(this@SuperActivity, R.color.transparent)
    WindowCompat.setDecorFitsSystemWindows(window, false)
    ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
      val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())

      view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
        leftMargin = insets.left
        rightMargin = insets.right
        bottomMargin = insets.bottom
      }
      WindowInsetsCompat.CONSUMED
    }
  }
    

  private fun showStatusBar() {
    window.statusBarColor = ContextCompat.getColor(this@SuperActivity, R.color.transparent)
    WindowCompat.setDecorFitsSystemWindows(window, true)
  }

我在调用隐藏方法的片段上得到了适当的行为。

但是当我点击另一个片段(需要显示状态栏的片段)时,出现以下行为:

下边距默认为0(或根布局中的指定值“binding.root”)

所以,您需要重新设置下边距;如果它已经是 0;那么你可以:

private fun showStatusBar() {
    window.statusBarColor = ContextCompat.getColor(this@SuperActivity, R.color.transparent)
    WindowCompat.setDecorFitsSystemWindows(window, true)

    ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
      val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())

      view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
        bottomMargin = 0 // reset the margin
      }
      WindowInsetsCompat.CONSUMED
    }
  }
}

或者如果是其他情况;然后你需要将它从 dp 转换为像素并将其设置为 bottomMargin

如果您在 binding.root 中有一些指定的边距值,同样适用;但我认为你没有,因为问题只出现在底部。

更新:

The method setOnApplyWindowInsetsListener is not called inside showStatusBar method. Because in this, the Window Insets are not changed. Since, we added margin in hideStatusBar method, so this space that you see below navigation bar is from hideStatusBar method.

虽然监听器应该被触发,但是你可以直接更新根:

binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
    bottomMargin = 0
}

但是请注意,setDecorFitsSystemWindows 可能需要一些时间才能更新,因此 updateLayoutParams 不会有效果,因此,您可能需要一点延迟:

Handler(Looper.getMainLooper()).postDelayed( {
    binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
        bottomMargin = 0
    }
 }, 0.1.toLong())