View.doOnAttach回调保证findViewById会返回视图吗?

问题描述 投票:0回答:1

我以编程方式创建

FrameLayout
。我给它唯一的 id -
myFrameLayoutId
- 并应用
View#doOnAttach
侦听器,然后添加到层次结构。

在侦听器中,我执行一个操作,该操作依赖于

findViewById(myFrameLayoutId)
。我开始收到非常罕见的崩溃,这意味着
findViewById(myFrameLayoutId)
有时会返回
null

因此我想知道:

  • 调用
    View.doOnAttach
    回调是否能保证
    View
    是可找到的?
  • 如果没有,推迟某些操作直到可以通过
    findViewById
    找到视图的那一刻,正确的方法是什么?
android android-fragments
1个回答
0
投票

1。调用View.doOnAttach回调是否保证View可找到?

不,doOnAttach回调不能保证可以通过findViewById找到视图。当视图附加到 window 时,会调用 doOnAttach 函数,但它不能保证视图层次结构已完全设置或父级已更新其子级引用。

2。推迟某些操作直到可以通过 findViewById 找到视图的时间点的正确方法是什么?

您可以使用

ViewTreeObserver.OnPreDrawListener
。在绘制视图之前调用此侦听器。此时,视图层次结构应该已完全建立,因此 findViewById 应该按预期工作。

示例:

val frameLayout = FrameLayout(context)
frameLayout.id = myFrameLayoutId

frameLayout.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
    override fun onPreDraw(): Boolean {
        frameLayout.viewTreeObserver.removeOnPreDrawListener(this) // Important to remove after being called

        // By this time, the view hierarchy should be ready
        val foundView = findViewById<View>(myFrameLayoutId)
        
        // Your logic here
        
        return true
    }
})

// Add the frameLayout to your view hierarchy

参考资料:

  • Android 官方文档提供了有关 ViewTreeObserver 及其各种侦听器(包括 OnPreDrawListener)的信息。

  • doOnAttach 函数是 Android KTX 库提供的 Kotlin 扩展函数。有关此内容的文档可以在Android KTX 参考中找到。

© www.soinside.com 2019 - 2024. All rights reserved.