Manipulador de estado do gerenciador de fragmentos

Importante

Este artigo descreve funcionalidades e diretrizes que estão em versão prévia pública e podem ser modificadas substancialmente antes de passarem para a disponibilidade geral. A Microsoft não faz nenhuma garantia, expressa ou implícita, com relação às informações fornecidas aqui.

O FragmentManagerStateHandler é uma classe que ajuda a restaurar fragmentos quando ocorre uma transição em um modo de tela.

O problema enfrentado durante as transições de modo de tela é que a atividade será recriada, mas a interface do usuário não é a mesma.

Por exemplo:

  • Não é preciso restaurar o fragmento de tela única ao fazer a transição para o modo de tela dupla.
  • Não é preciso restaurar o fragmento de tela dupla ao fazer a transição para o modo de tela única.

O componente detectará automaticamente o modo de tela atual e vai restaurar somente os fragmentos necessários, de acordo com o modo de tela.

Importante

O componente funciona somente com atividades do AndroidX.

Como usar

class SampleApp : Application() {
    override fun onCreate() {
        super.onCreate()
        ScreenManagerProvider.init(this)
        FragmentManagerStateHandler.init(this)
    }
}
class SampleActivity : FragmentActivity(), ScreenInfoListener {
    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)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        ScreenManagerProvider.getScreenManager().onConfigurationChanged()
    }

    override fun onStart() {
        super.onStart()
        ScreenManagerProvider.getScreenManager().addScreenInfoListener(this)
    }

    override fun onPause() {
        super.onPause()
        ScreenManagerProvider.getScreenManager().removeScreenInfoListener(this)
    }

    /**
     * Called whenever the screen info was changed.
     * @param screenInfo object used to retrieve screen information
     */
    override fun onScreenInfoChanged(screenInfo: ScreenInfo) {
        when {
            screenInfo.isDualMode() -> 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()
}