ViewPager2 OnApplyWindowInsetsListener未调用

时间:2019-12-05 12:42:03

标签: android android-viewpager2 windowinsets

我在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来说可以正常工作)。

2 个答案:

答案 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