https://kotlinlang.org logo
Title
d

Damian Kwaśniak

01/11/2022, 11:18 AM
Hi, I have a RecyclerView where my ViewHolder has XML view inside. One of its children is ComposeView. Following the documentation of Interoperability APIs, I set view composition strategy like this:
setViewCompositionStrategy(DisposeOnViewTreeLifecycleDestroyed)
It works fine as long as I am not updating the view when it is still attached to the window. If so, I get an exception added in thread. 1. User enters the RecyclerView where each item has show more button 2. User press show more button what causes the view to redraw (bind method from ViewHolder is called) 3. crash Any ideas?
:thread-please: 1
😬 1
java.lang.IllegalStateException: View tree for androidx.compose.ui.platform.ComposeView{f43c13c G.E...... ......ID 58,413-912,470 #7f090115 app:id/contactOpportunityItemRelatedContactsComposeView} has no ViewTreeLifecycleOwner
        at androidx.compose.ui.platform.ViewCompositionStrategy$DisposeOnViewTreeLifecycleDestroyed.installFor(ViewCompositionStrategy.android.kt:109)
        at androidx.compose.ui.platform.AbstractComposeView.setViewCompositionStrategy(ComposeView.android.kt:136)
        at com.siemens.presentation.contactdetails.viewholder.opportunity.OpportunityViewHolder.bind(OpportunityViewHolder.kt:78)
        at com.siemens.presentation.contactdetails.viewholder.opportunity.OpportunityViewHolder.bind(OpportunityViewHolder.kt:49)
        at com.siemens.presentation.accountdetails.AccountDetailsAdapter.onBindViewHolder(AccountDetailsAdapter.kt:136)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4012)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4578)
a

Arjun Achatz

01/11/2022, 12:52 PM
Try ViewCompositionStrategy.DisposeOnLifecycleDestroyed
I remember something about the docs not being exactly right about this one
d

Damian Kwaśniak

01/11/2022, 2:00 PM
What I did is:
binding.lifecycleOwner?.let {
                val strategy = ViewCompositionStrategy.DisposeOnLifecycleDestroyed(it)
                setViewCompositionStrategy(strategy)
            }
and in the init block of my ViewHolder I have to set binding's lifecycleOwner manually with:
init {
        binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
    }
but I am not sure if this solution is an equivalent of whet they suggest in the documentation
according to the documentation these two strategies work differently