在片段更改时恢复窗口插图
Posted
技术标签:
【中文标题】在片段更改时恢复窗口插图【英文标题】:Reverting Window Insets on fragment change 【发布时间】:2021-12-23 15:19:24 【问题描述】:我有三个片段。我想在一个片段上应用透明状态栏。为此,我在底部导航栏的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)
我在片段调用隐藏方法时得到了适当的行为。
但是当我点击另一个片段(需要显示状态栏的片段)时,我得到以下行为:
【问题讨论】:
您是否将这个WindowCompat.setDecorFitsSystemWindows(window, false)
还原为其他片段?
是的。正如您在 showStatusBar() 方法中看到的那样。我使用 WindowCompat.setDecorFitsSystemWindows(window, true) 恢复了这个
【参考方案1】:
下边距默认为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 中有一些指定的边距值,则同样适用;但我认为你没有,因为问题只出现在底部。
更新:
setOnApplyWindowInsetsListener 方法不会在 showStatusBar 方法中调用。因为在这种情况下,Window Insets 没有改变。由于我们在 hideStatusBar 方法中添加了边距,所以您在导航栏下方看到的这个空间来自 hideStatusBar 方法。
虽然应该触发监听,但是可以直接更新root:
binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams>
bottomMargin = 0
但请注意,setDecorFitsSystemWindows
可能需要一些时间才能更新,因此updateLayoutParams
不会产生效果,因此,您可能需要稍作延迟:
Handler(Looper.getMainLooper()).postDelayed(
binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams>
bottomMargin = 0
, 0.1.toLong())
【讨论】:
但是最好有一个ViewCompat.setOnApplyWindowInsetsListener
来处理这两种情况;你可以做一个简单的条件
不。在 showStatusBar 方法中不调用 setOnApplyWindowInsetsListener 方法。因为在这种情况下,Window Insets 没有改变。因为,我们在 hideStatusBar 方法中添加了边距,所以您在导航栏下方看到的这个空间来自 hideStatusBar 方法。这就是为什么我要将窗口插图还原为初始插图的原因
是的。谢谢@Zain。这就是修复。您能否也更新答案中的最后一条评论。这样我就可以批准它
欢迎@TahaAsif.. 但请注意,这可能因设备而异。根据我的测试,直接调用没有效果;我不得不对此稍作延迟;我也更新了答案
非常感谢@Zain。祝好运。批准您的回答。以上是关于在片段更改时恢复窗口插图的主要内容,如果未能解决你的问题,请参考以下文章