0

I added jetpack compose into my old project and I have noticed one problem with fragmentManager work.

In short, I have the following transactions:

MainActivity -> SettingsFragment -> BackgroundSettingsFragment.

When we go to BackgroundSettingsFragment and we press a back button, we return to SettingsFragment, but its content is empty. I debbuged SettingsFragment, after returning here, everything looks fine, but layout field is just empty. I added breakpoints to different lifecycle events (onCreate, onCreateView, onViewCreated). Everything works great, I see that resources also is fine.

Without jetpack compose dependencies, there is no problem.

In details, I have the following code.

    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
        kotlinCompilerVersion "$rootProject.kotlinVersion"
    }

    // Dependencies

    // --- Jetpack Compose ---
    implementation "androidx.compose.ui:ui:$compose_version"
    // Integration with activities
    implementation "androidx.activity:activity-compose:1.5.1"
    // Integration with ViewModels
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
    // Tooling support (Previews, etc.)
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    // Foundation (Border, Background, Box, Image, Scroll, shapes, animations, etc.)
    implementation 'androidx.compose.foundation:foundation:1.2.0'
    // Material Design
    implementation "androidx.compose.material:material:$compose_version"
    // Material design icons
    implementation "androidx.compose.material:material-icons-core:$compose_version"
    implementation "androidx.compose.material:material-icons-extended:$compose_version"
    // Integration with observables
    implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
    implementation "androidx.compose.runtime:runtime-rxjava2:$compose_version"
    // Navigation
    implementation "androidx.navigation:navigation-compose:2.5.1"
    implementation "androidx.hilt:hilt-navigation-compose:1.0.0"


MainActivity:

class MainActivity : RxAppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(layout)
        
        redirectToSettingsFragment()
    }
    
    fun redirectToSettingsFragment() {
        replaceFragmentSafely(SettingsFragment(), R.id.contentFrame)
    }
}

SettingsFragment:

class SettingsFragment : RxFragment() {
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        setupToolbar()
        setupView()
    }

    fun setupView() {
        label.setText(R.string.background_settings)
        value.setText(R.string.color)
    }
    
    fun setupToolbar() {
        (activity as MainActivity).toolbar.setOnBackButtonClickListener { 
            activity?.onBackPressed()
        }
    }
    
    fun redirectToSecondFragment() {
        replaceFragmentSafely(BackgroundSettingsFragment(), R.id.contentFrame, allowBackStack = true)
    }
}

BackgroundSettingsFragment:

class BackgroundSettingsFragment : RxFragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        setupToolbar()
    }
    
    fun setupToolbar() {
        (activity as MainActivity).toolbar.setOnBackButtonClickListener { 
            activity?.onBackPressed()
        }
    }
}
fun AppCompatActivity.replaceFragmentSafely(fragment: Fragment,
                                            @IdRes containerViewId: Int,
                                            allowBackStack: Boolean = false) {
    val fm = supportFragmentManager
            .beginTransaction()
            .replace(containerViewId, fragment, fragment.javaClass.toString())

    if (allowBackStack) fm.addToBackStack(null)

    try {
        if (!supportFragmentManager.isStateSaved) {
            fm.commit()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

Here is the result. What SettingsFragment looks like before we go to the BackgroundSettingsFragment:

enter image description here

What SettingsFragment looks like after we returned from the BackgroundSettingsFragment:

enter image description here

Please help, maybe someone already faced such a problem.

San
  • 64
  • 1
  • 6
  • I can see the XML code only, Why did you add Jetpack Compose dependencies? – SemicolonSpace Aug 08 '22 at 06:34
  • @SemicolonSpace Our team plan to gradually migrate to new technologies. But it seems to be difficult to combine two different generations (old features with jetpack compose) – San Aug 08 '22 at 09:39
  • I added setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) inside the fragments and created views using the Compose. Everything worked great. They mentioned some use cases here : https://developer.android.com/jetpack/compose/interop/interop-apis#compose-in-fragments Try them. – SemicolonSpace Aug 08 '22 at 10:13
  • Hi! @SemicolonSpace Have you found a solution to the problem? – kvazik Dec 23 '22 at 08:27
  • Hi! @San Have you found a solution to the problem? – kvazik Dec 23 '22 at 09:00
  • Hi @kvazik. Unfortunately no. I had to abandon the idea of adding jetpack compose to the project. I think that this problem will not happen if we use the navigation component, but we cannot use it in our project, because already too much legacy code. – San Dec 23 '22 at 12:00
  • 1
    I had the same problem, try to follow this [solution]:(https://stackoverflow.com/questions/72781705/jetpack-compose-view-not-drawing-when-coming-back-to-fragment) – edoedo91 May 09 '23 at 08:11

1 Answers1

1

I had the same problem and was able to ... well, work around it :/

It seems that Kotlinx-synthetics (which you also seem to be using) and fragment back navigation do not work well with compose. As soon as I had migrated from Kotlinx-synthetics to view-binding, the bug was gone. See the official migration guide here: https://developer.android.com/topic/libraries/view-binding/migration

I hope it helps; cheers.

Younes Charfaoui
  • 1,059
  • 3
  • 10
  • 20
ph-pdy
  • 11
  • 1