Search code examples
androidandroid-fragments

Does View.doOnAttach callback guarantee that findViewById will return the view?


I create FrameLayout programmatically. I give it unique id - myFrameLayoutId - and apply View#doOnAttach listener, and then add to the hierarchy.

Within the listener I perform an operation, which relies on findViewById(myFrameLayoutId). I've begun receiving very rare crash, which implies that findViewById(myFrameLayoutId) returns null sometimes.

Thus I wonder:

  • Does call to the View.doOnAttach callback guarantees that View is findable?
  • If not, what is a correct way to postpone some action until the point, when the view can be found by the findViewById?

Solution

  • 1. Does the call to View.doOnAttach callback guarantee that View is findable?

    No, the doOnAttach callback does not guarantee that the View is findable via findViewById. The doOnAttach function is called when the view is attached to a window, but it does not guarantee that the view hierarchy is completely set up or that the parent has updated its child references.

    2. What is the correct way to postpone some action until the point when the view can be found by the findViewById?

    You can use ViewTreeObserver.OnPreDrawListener. This listener is called before drawing a view. By this time, the view hierarchy should be fully established, so findViewById should work as expected.

    Example:

    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
    

    References:

    • The official Android documentation provides information on ViewTreeObserver and its various listeners, including the OnPreDrawListener.

    • The doOnAttach function is a Kotlin extension function provided by the Android KTX library. The documentation for this can be found in the Android KTX reference.