Gerenciador de tela do Surface Duo

Cuidado

Esse componente foi preterido e não tem mais suporte.

Para recuperar informações sobre a área de exibição e o recurso de dobra, você deve usar o Gerenciador de Janelas do Jetpack.

Como alternativa, use um desses layouts e controles de tela dupla que podem se adaptar automaticamente a dispositivos de tela dupla e dobráveis.

SurfaceDuoScreenManager é o protocolo comum para duas implementações de gerenciador de tela distintas, uma usando a biblioteca DisplayMask da Microsoft e a outra usando a biblioteca WindowManager do Google. Esta interface define métodos que você deve usar para registrar e cancelar o registro de ouvintes de informações de tela.

Para criar o gerenciador de tela, você deve usar ScreenManagerProvider.getScreenManager(), que retornará a instância singleton da implementação de SurfaceDuoScreenManager. Antes de chamar esse método, você deve chamar ScreenManagerProvider.init(Application) dentro de Application.onCreate() para inicializar a instância singleton de SurfaceDuoScreenManager. Esta chamada é necessária; caso contrário, será gerada uma exceção IllegalStateException("SurfaceDuoScreenManager must be initialized inside Application#onCreate()"). Depois de obter a instância de SurfaceDuoScreenManager, você pode registrar o retorno de chamada ScreenInfoListener usando SurfaceDuoScreenManager.addScreenInfoListener(ScreenInfoListener?) para receber uma notificação quando o modo de tela for alterado. Lembre-se de que você também pode adicionar vários ouvintes. Portanto, faça o cancelamento do registro usando SurfaceDuoScreenManager.removeScreenInfoListener(ScreenInfoListener?) para evitar vazamentos de memória.

Além disso, se você decidiu lidar com as alterações de configuração, chame SurfaceDuoScreenManager.onConfigurationChanged(Configuration) de Activity. Caso contrário, o retorno de chamada não será acionado.

class SampleApp : Application() {
    override fun onCreate() {
        super.onCreate()
        ScreenManagerProvider.init(this)
    }
}
class SampleActivity : AppCompatActivity(), ScreenInfoListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)
    }

    override fun onScreenInfoChanged(screenInfo: ScreenInfo) {
        if (screenInfo.isDualMode()) {
            // TODO: Add dual-screen behavior.
        } else {
            // TODO: Add single-screen behavior.
        }
    }

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

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

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

Outra opção que você tem para recuperar o objeto ScreenInfo sem a necessidade de registrar um retorno de chamada é usar o método ScreenInfoProvider.getScreenInfo(Context). Lembre-se de que você deve chamar esse método depois que a exibição for anexada à janela; caso contrário, alguns métodos de ScreenInfo retornarão null ou lançarão exceções.

class SampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)

        window?.decorView?.rootView?.let { rootView ->
            if (ViewCompat.isAttachedToWindow(rootView)) {
                val screenInfo = ScreenInfoProvider.getScreenInfo(this)
            } else {
                rootView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
                    override fun onViewAttachedToWindow(view: View) {
                        rootView.removeOnAttachStateChangeListener(this)
                        val screenInfo = ScreenInfoProvider.getScreenInfo(this)
                    }

                    override fun onViewDetachedFromWindow(view: View) {}
                })
            }
        }
    }
}

Se você estiver usando a biblioteca Core Ktx, então:

class SampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)

        window?.decorView?.rootView?.doOnAttach {
            val screenInfo = ScreenInfoProvider.getScreenInfo(this)
        }
    }
}