jakepurple13
jakepurple13

Reputation: 151

Jetpack Compose In Fragment doesn't recompose on popbackstack

I'm using the jetpack navigation component here, not the Compose Navigation Component since there are some areas in my app I cannot convert yet.

The issue I'm running into is:

Fragment A starts and contains a ComposeView in it's xml. Fragment A opens Fragment B. But, when you return to Fragment A, the ComposeView is empty and doesn't show anything.

Is this a bug? Is this known? Am I just doing something wrong? I looked into setting the view composition strategy and tried each option and none of them worked.

Upvotes: 1

Views: 1541

Answers (1)

jakepurple13
jakepurple13

Reputation: 151

I found the answer. I had a BaseFragment:

abstract class BaseFragment : Fragment() {

    private var hasInitializedRootView = false
    private var rootView: View? = null

    protected abstract val layoutId: Int

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return getPersistentView(inflater, container, savedInstanceState, layoutId)
    }

    private fun getPersistentView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?, layout: Int): View? {
        if (rootView == null) {
            // Inflate the layout for this fragment
            rootView = inflater?.inflate(layout, container, false)
        } else {
            // Do not inflate the layout again.
            // The returned View of onCreateView will be added into the fragment.
            // However it is not allowed to be added twice even if the parent is same.
            // So we must remove rootView from the existing parent view group
            // (it will be added back).
            (rootView?.parent as? ViewGroup)?.removeView(rootView)
        }

        return rootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if (!hasInitializedRootView) {
            hasInitializedRootView = true
            viewCreated(view, savedInstanceState)
        }
    }

    abstract fun viewCreated(view: View, savedInstanceState: Bundle?)
}

What would happen is that onCreateView wouldn't be called as wanted and the composition wouldn't restart. Changing to using a normal Fragment fixed this perfectly.

Upvotes: 1

Related Questions