Android Fragments View.doOnAttach回调是否保证findViewById将返回视图?

tquggr8v  于 12个月前  发布在  Android
关注(0)|答案(1)|浏览(136)

FrameLayout是用程序设计的。我给予它唯一的id -myFrameLayoutId-并应用View#doOnAttach侦听器,然后添加到层次结构中。
在侦听器中,我执行一个依赖于findViewById(myFrameLayoutId)的操作。我已经开始收到非常罕见的崩溃,这意味着findViewById(myFrameLayoutId)有时会返回null
因此我想知道:

  • View.doOnAttach回调的调用是否保证View是可找到的?
  • 如果没有,什么是正确的方法来推迟一些行动,直到点,当视图可以找到的findViewById
zdwk9cvp

zdwk9cvp1#

1.调用View.doOnAttach回调函数是否保证View是可找到的?

不可以,doOnAttach回调并不保证可以通过findViewById找到View。doOnAttach函数在视图附加到 window 时被调用,但它不保证视图层次结构已完全建立,也不保证父视图已更新其子引用。

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及其各种侦听器的信息,包括OnPreDrawtrix。
  • doOnAttach函数是Android KTX库提供的一个Kotlin扩展函数。相关文档可以在Android KTX参考中找到。

相关问题