androidbroadcast / ViewBindingPropertyDelegate

Make work with Android View Binding simpler
https://proandroiddev.com/make-android-view-binding-great-with-kotlin-b71dd9c87719
Apache License 2.0
1.42k stars 102 forks source link

IllegalStateException: Fragment's view can't be accessed. #104

Closed yoobi closed 2 years ago

yoobi commented 2 years ago

Hello, I'm using 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6' And I get this exception for one of my page however I don't understand why.

private val binding: FragmentListVideosBinding by viewBinding(FragmentListVideosBinding::bind,
    onViewDestroyed = { it.rvVideos.adapter = null }
)
private val myAdapter = MyAdapter()

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

    myAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            if (positionStart == 0) binding.rvVideos.scrollToPosition(0) // This line creates the exception
        }
    })
    binding.rvVideos.adapter = myAdapter
 }

The stacktrace

Fatal 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.getLifecycleOwner(FragmentViewBindings.kt:52)
       at com.my.application.ui.listvideos.ListVideosFragment.<clinit>(ListVideosFragment.kt:41)
       at com.my.application.ui.listvideos.ListVideosFragment.access$getBinding(ListVideosFragment.java:39)
       at com.my.application.ui.listvideos.ListVideosFragment$onViewCreated$2$1.onItemRangeInserted(ListVideosFragment.kt:82)
       at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyItemRangeInserted(RecyclerView.java:12684)
       at androidx.recyclerview.widget.RecyclerView$Adapter.notifyItemRangeInserted(RecyclerView.java:7722)
       at androidx.recyclerview.widget.AdapterListUpdateCallback.onInserted(AdapterListUpdateCallback.java:42)
       at androidx.paging.OverlappingListsDiffDispatcher$PlaceholderUsingUpdateCallback.dispatchInsertAsPlaceholderBefore(NullPaddedListDiffHelper.kt:343)
       at androidx.paging.OverlappingListsDiffDispatcher$PlaceholderUsingUpdateCallback.onInserted(NullPaddedListDiffHelper.kt:310)
       at androidx.recyclerview.widget.BatchingListUpdateCallback.dispatchLastEvent(BatchingListUpdateCallback.java:61)
       at androidx.recyclerview.widget.DiffUtil$DiffResult.dispatchUpdatesTo(DiffUtil.java:967)
       at androidx.paging.OverlappingListsDiffDispatcher.dispatchDiff(OverlappingListsDiffDispatcher.java:208)
       at androidx.paging.NullPaddedListDiffHelperKt.dispatchDiff(NullPaddedListDiffHelperKt.java:127)
       at androidx.paging.AsyncPagingDataDiffer$differBase$1.presentNewList(AsyncPagingDataDiffer.kt:102)
       at androidx.paging.AsyncPagingDataDiffer$differBase$1$presentNewList$1.invokeSuspend(AsyncPagingDataDiffer.kt:16)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
       at android.os.Handler.handleCallback(Handler.java:938)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:257)
       at android.app.ActivityThread.main(ActivityThread.java:8368)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1032)

Could it be possible that myAdapter keeps a reference of the registerAdapterDataObserver after being destroyed ?

kirich1409 commented 2 years ago

Is the Fragment part of ViewPager ?

yoobi commented 2 years ago

No, it's a simple Recyclerview with paging3

kirich1409 commented 2 years ago

Please check that onViewDestroyed isn't called before data observer callbacks You need to unregister data observer in onViewDestroyed too

yoobi commented 2 years ago

It might be the issue indeed, I should unregister the callback in onViewDestroyed. I'll change this in my app and close the issue in a few days if I do not get more report.

Thank you !

zhangjinhuang commented 1 year ago

I've also had this problem with the fragment, but it's not necessary library version is: (noreflection:1.5.9),when I use below code private val binding by viewBinding(HomeAnswerBookFragmentBinding::bind)

kirich1409 commented 1 year ago

@zhangjinhuang , it's important from where and when in Fragment's lifecycle you access delegate not how you create it