1

I'm using viewBinding successfully and never encountered this problem before. The property is initialized in onViewCreated like so:

private lateinit var viewBinding: FragmentMainBinding

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    // Create a binding object to the layout
    viewBinding = FragmentMainBinding.bind(view)
}

I then have a button which opens the camera, like so (also in onViewCreated):

// Button to open camera
viewBinding.takePictureButton.setOnClickListener {
    findNavController().navigate(R.id.action_main_fragment_to_camera)
}

My main fragment implements an interface function declared in the camera fragment. This is to know whether the user picked an image or dismissed the camera without picking an image. Like so:

// Interface declared in CameraFragment
interface ImageCaptureListener {
    fun onUserDismissedCamera(userPickedImage: Boolean)
}

// Implementation of interface function in main fragment
override fun onUserDismissedCamera(userPickedImage: Boolean) {
    if(userPickedImage) {
        println("User picked image")
        
        //** The app crashes when trying to set image in viewBinding.mainFragmentImageView

    } else {
        println("User did NOT picked image")
    }
}

How can my viewBinding property not be initialized here? It obviously is when navigating to camera fragment. Is this a lifecycle issue of some sort? Is it deinitialized when navigating to camera?

Thankful for any pointers.

Dan Abnormal
  • 1,188
  • 11
  • 21

1 Answers1

0

View is destroyed when you are navigating to another Fragment, so binding is not valid anymore. Normally this would be solved by setting retainInstance to true in the Fragment onViewCreated, but it is deprecated now (although I disagree with deprecation, but Google noobs only think that apps can be simple only so reloading complex layouts now will be an expensive thing). You can use retainInstance, or set the returned photo object from the callback to some variable and set it when onCreateView is called.

Bio-Matic
  • 793
  • 1
  • 8
  • 20
  • Thanks for the reply. I will try doing it the variable-way. – Dan Abnormal May 12 '21 at 11:59
  • I wouldn't ever endorse an approach with 'retainInstance', the use of it was almost always incorrect and error prone so the deprecation makes sense. Their reasoning behind it in the documentation describes a better approach. – Henry Twist May 12 '21 at 13:42
  • retainInstance is not about restoring state, it’s about having an already initialized view object. If you write plain boring apps then yeah, retainInstance should not be used. But imagine you have a ViewPager with 5 complex Fragment views there and they are recreated each time user gets back to the ViewPager screen. Sometimes it does make sense retaining view objects when the allocation is expensive. Sometimes it’s not enough flattening view hierarchy, sometimes views are just bloody expensive to draw, especially on older devices. – Bio-Matic May 12 '21 at 16:39
  • 1
    @Bio-Matic, I got my question answered and learned something new. Thanks again! I already had a viewModel set up so I fixed the passing of the bitmap that way. – Dan Abnormal May 12 '21 at 19:41