我在ViewPager2
的一个片段上有一个FAB,在边对边时应注意窗口插图。我在FAB上添加了OnApplyWindowInsetsListener
,以更新其边距。使用旧的ViewPager
时,这种方法可以正常工作。
更新为ViewPager2
时,似乎OnApplyWindowInsetsListener
开头没有被调用。但是,当我启动ActionMode
时。然后,调用侦听器并使用新的边距,直到我离开父Fragment。
我已经分叉了演示项目来说明问题。请参见https://github.com/hardysim/views-widgets-samples/tree/edge-to-edge上分支ParallelNestedScrollingActivity
上的示例“ {嵌套嵌套的RecyclerViews ViewPager2”示例(edge-to-edge
)。
在这里,我向在ViewPager2页面上使用的(嵌套)RecyclerView
中添加了FAB,并将Activity-UI设置为“边到边”(请参见View.goEdgeToEdge()
)。然后,FAB位于导航栏的后面,我们需要更新其边距以添加窗口插图。
这是它不起作用的地方(但是对于旧的ViewPager
来说可以正常工作)。
答案 0 :(得分:2)
此问题已在最初被问到的issue tracker中得到了回答:
这里的问题是,在分派窗口插图时,页面尚未附加到视图层次结构。附加视图时,系统不会使用当前插入物调用
OnApplyWindowInsetsListener
,因此,将视图附加到层次结构时,您必须调用requestApplyInsets()
。
所以我创建了一个小助手
/**
* Call this everytime when using [ViewCompat.setOnApplyWindowInsetsListener]
* to ensure that insets are always received.
*/
private fun View.requestApplyInsetsWhenAttached() {
// https://chris.banes.dev/2019/04/12/insets-listeners-to-layouts/
if (isAttachedToWindow) {
// We're already attached, just request as normal
requestApplyInsets()
} else {
// We're not attached to the hierarchy, add a listener to request when we are
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
v.removeOnAttachStateChangeListener(this)
v.requestApplyInsets()
}
override fun onViewDetachedFromWindow(v: View) = Unit
})
}
}
在ViewCompat.setOnApplyWindowInsetsListener()
上调用View
之后立即被调用:
ViewCompat.setOnApplyWindowInsetsListener(view) { view, insets ->
// [do stuff]
insets
}
view.requestApplyInsetsWhenAttached()
答案 1 :(得分:1)
似乎是ViewPager2
的实现错误。
寻呼机首次获取我们创建的视图时,寻呼机为其调用requestApplyInsets
。但是很遗憾,该视图未附加父视图,因此requestApplyInsets
的调用无效。
可以通过在View.OnAttachStateChangeListener
上添加调用requestApplyInsets
的{{1}}来解决。
您的onViewAttachedToWindow
样本在以下方面表现良好:
ParallelNestedScrollingActivity