Gestionnaire d’état du gestionnaire de fragments

Important

Les fonctionnalités et l’aide décrites dans cet article sont en préversion publique et peuvent faire l’objet de modifications importantes avant leur lancement en disponibilité générale. Microsoft ne donne aucune garantie, expresse ou implicite, concernant les informations fournies ici.

La classe FragmentManagerStateHandler permet de restaurer des fragments lorsqu’un changement de mode d’écran se produit.

Quand nous faisons passer l’application du mode double écran en mode écran simple, tous les fragments sont recréés, même s’ils ne sont pas visibles.

À l’aide de cette bibliothèque, seuls les fragments nécessaires sont recréés.

Les fragments sont restaurés à partir du pack d’activités. Cette approche comporte deux packs qui sont échangés au moment de l’exécution en fonction du mode d’étendue. Il existe un pack pour l’écran unique et un autre pour le mode étendu. Cela n’est possible que par l’ajout d’un rappel du cycle de vie de l’activité et par l’échange de ces deux packs dans le rappel onActivityPreCreated.

Le composant détecte automatiquement le mode d’écran. Il ne restaure que les fragments dont nous avons besoin, en fonction du mode d’écran.

Important

Le composant fonctionne uniquement avec les activités d’AndroidX.

Procédure d’utilisation

class SampleApp : Application() {
    override fun onCreate() {
        super.onCreate()
        FragmentManagerStateHandler.init(this)
    }
}
class SampleActivity : AppCompatActivity() {
    companion object {
        private const val FRAGMENT_DUAL_START = "FragmentDualStart"
        private const val FRAGMENT_DUAL_END = "FragmentDualEnd"
        private const val FRAGMENT_SINGLE_SCREEN = "FragmentSingleScreen"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)
        registerWindowInfoFlow()
    }

    private fun registerWindowInfoFlow() {
        val windowInfoRepository = windowInfoRepository()
        lifecycleScope.launch(Dispatchers.Main) {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                windowInfoRepository.windowLayoutInfo.collectIndexed { index, info ->
                    if (index == 0) {
                        onScreenInfoChanged(info)
                    }
                }
            }
        }
    }

    /**
     * Called whenever the screen info was changed.
     * @param windowLayoutInfo object used to retrieve screen information
     */
    private fun onScreenInfoChanged(windowLayoutInfo: WindowLayoutInfo) {
        when {
            windowLayoutInfo.isInDualMode() -> setupDualScreenFragments()
            else -> setupSingleScreenFragments()
        }
    }

    /**
     * Adds fragments for the single screen mode
     */
    private fun setupSingleScreenFragments() {
        if (supportFragmentManager.findFragmentByTag(FRAGMENT_SINGLE_SCREEN) == null) {
            supportFragmentManager.inTransaction {
                replace(R.id.first_container_id, SingleScreenFragment(), FRAGMENT_SINGLE_SCREEN)
            }
        }
    }

    /**
     * Adds fragments for the dual screen mode
     */
    private fun setupDualScreenFragments() {
        if (supportFragmentManager.findFragmentByTag(FRAGMENT_DUAL_START) == null &&
            supportFragmentManager.findFragmentByTag(FRAGMENT_DUAL_END) == null
        ) {
            supportFragmentManager.inTransaction {
                replace(R.id.first_container_id, DualStartFragment(), FRAGMENT_DUAL_START)
            }

            supportFragmentManager.inTransaction {
                replace(R.id.second_container_id, DualEndFragment(), FRAGMENT_DUAL_END)
            }
        }
    }
}

inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> Unit) {
    val fragmentTransaction = beginTransaction()
    fragmentTransaction.func()
    fragmentTransaction.commit()
}

Étapes suivantes

Découvrez d’autres bibliothèques de dispositions double écran.