Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IllegalStateException when using viewBinding for onCreateView #101

Open
gabrielfeo opened this issue Apr 20, 2022 · 14 comments
Open

IllegalStateException when using viewBinding for onCreateView #101

gabrielfeo opened this issue Apr 20, 2022 · 14 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@gabrielfeo
Copy link

Trying to update to 1.5.2+, I find this usage causes a crash due to a new internal check in the library.

    private val binding by viewBinding {
        OnboardingContainerFragmentBinding.inflate(layoutInflater)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View = binding.root
IllegalStateException: Fragment’s view can’t be accessed. Fragment’s view is null.
Maybe you try to access view before onViewCreated() or after onDestroyView().
Add check `if (view != null)` before call ViewBinding

The change is stated in the changelog, but I don't see anything inherently wrong with the above usage considering the viewBinding lambda is invoked lazily. Do you see a way to keep it (we have many in the project) when upgrading to 1.5.2+?

@kirich1409 kirich1409 self-assigned this Apr 24, 2022
@kirich1409 kirich1409 added the bug Something isn't working label Apr 24, 2022
@kirich1409 kirich1409 added this to the 1.5.7 milestone Apr 24, 2022
@kirich1409
Copy link
Collaborator

Please try version 1.5.6

@ddello32
Copy link

I've have been facing the same issue with version 1.5.6

@kirich1409
Copy link
Collaborator

@gabrielfeo from what places you access viewBinding delegate?

@cmorigaki
Copy link

@kirich1409 I could replicate the problem using the sample app adjusting the way we setup the Fragment view. Instead of referecing the xml, using the Binding generated class

from:

class ProfileFragment : Fragment(R.layout.fragment_profile) {

    private val viewBinding by viewBinding(FragmentProfileBinding::bind,
        onViewDestroyed = { _: FragmentProfileBinding ->
            // reset view
        })

to:

class ProfileFragment : Fragment() {

    private val viewBinding by viewBinding(FragmentProfileBinding::bind,
        onViewDestroyed = { _: FragmentProfileBinding ->
            // reset view
        })

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ) = viewBinding.root

@rpavliuk
Copy link

Is it possible to fix this without removing the XML referencing?

@rpavliuk
Copy link

rpavliuk commented Apr 14, 2023

@gabrielfeo from what places you access viewBinding delegate?

@kirich1409 In my case, I'm accessing the viewBinding delegate in the onViewCreated method. This should be ok. Is it?

@kirich1409
Copy link
Collaborator

Yes. onCreateView() only need to inflate view from XML or create in code. Only after the callback method Fragment.getView() will return View connected with Fragment. That why all view initialization must be done in onViewCreated independently are you using ViewBinding or not.

@kirich1409
Copy link
Collaborator

kirich1409 commented Apr 15, 2023

Another variant is

class ProfileFragment : Fragment() {
    private val viewBinding: ProfileBinding by viewBinding(createMethod = CreateMethod.INFLATE)

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ) = viewBinding.root
}

it will work because ViewBindingPropdetyDelegate will call ViewBinding.inflate method via reflection. It's slower and not recommended.

Prefer to use

class ProfileFragment : Fragment(R.layout.profile) {
    private val viewBinding: ProfileBinding by viewBinding(ProfileBinding::bind)
}

@kirich1409
Copy link
Collaborator

By default the library prevent using viewBinding delegate before onViewCreated() will return the result. That's why crash happens. It's expected behaviour. I will think about @gabrielfeo case will work without turning off the check

@mahmud0v
Copy link

mahmud0v commented May 6, 2024

@kirich1409 Crash happened on android 13, 14 version which is using viewBinding delegate 1.5.9 version . I used this type

class ProfileFragment : Fragment(R.layout.profile) {
    private val viewBinding: ProfileBinding by viewBinding(ProfileBinding::bind)
}

Exception java.lang.IllegalStateException: Fragment's view can't be accessed. Fragment isn't added
at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue (ViewBindingProperty.kt:87)
at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue (FragmentViewBindings.kt:63)
at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue (FragmentViewBindings.kt:52)

I replaced this code part it worked:

class ProfileFragment : Fragment(R.layout.profile) {
    private var _binding: ProfileBinding? = null
    private val binding get() = _binding!!

   override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        _binding = ProfileBinding.inflate(inflater, container, false)
        return binding.root
    }
}

@fearsom03
Copy link

any updates on this issue ?

@mahmud0v
Copy link

any updates on this issue ?
I don't have any info about this update. Do you have the same issue when using viewBinding delegate with 13, 14 android version

@kirich1409
Copy link
Collaborator

I understand the issue. Try to reproduce it and fix on weekend

@kirich1409
Copy link
Collaborator

As solution I recommend to set XML layout in Fragment constructor and use ViewBindingDelegate without without inflating view and it will wrap Fragment.getView()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants