Administrador de pantallas de Surface Duo

Precaución

Este componente ha quedado en desuso y ya no se admite.

Para recuperar información sobre el área de presentación y la característica de plegado, debe usar el Administrador de ventanas de Jetpack.

Como alternativa, use uno de estos controles y diseños de doble pantalla que se pueden adaptar automáticamente a dispositivos de doble pantalla y dispositivos plegables.

SurfaceDuoScreenManager es el protocolo común para dos implementaciones de administrador de pantalla diferentes, una con la biblioteca de Microsoft DisplayMask y la otra con la biblioteca de Google WindowManager. Esta interfaz define los métodos que debe usar para el registro y la anulación del registro de los agentes de escucha de información de pantalla.

Para crear el administrador de pantalla, debe usar ScreenManagerProvider.getScreenManager(), que devolverá la instancia singleton de la implementación SurfaceDuoScreenManager. Antes de llamar a este método, debe llamar a ScreenManagerProvider.init(Application) dentro de su Application.onCreate() para inicializar la instancia singleton de SurfaceDuoScreenManager. Esta llamada es obligatoria; de lo contrario, se producirá una excepción IllegalStateException("SurfaceDuoScreenManager must be initialized inside Application#onCreate()"). Una vez que tenga la instancia de SurfaceDuoScreenManager, puede registrar la devolución de llamada de ScreenInfoListener mediante SurfaceDuoScreenManager.addScreenInfoListener(ScreenInfoListener?) para recibir una notificación cuando el modo de pantalla cambie. Tenga en cuenta que también puede agregar varios agentes de escucha, por lo que debe anular su registro mediante SurfaceDuoScreenManager.removeScreenInfoListener(ScreenInfoListener?) para evitar pérdidas de memoria.

Además, si decidió controlar los cambios de configuración, debe llamar a SurfaceDuoScreenManager.onConfigurationChanged(Configuration) desde su Activity; de lo contrario, la devolución de llamada no se desencadenará.

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()
    }
}

Otra opción que tiene que recuperar el objeto ScreenInfo sin necesidad de registrar una devolución de llamada es usar el método ScreenInfoProvider.getScreenInfo(Context). Tenga en cuenta que debe llamar a este método después de adjuntar la vista a la ventana; de lo contrario, algunos métodos de ScreenInfo devolverán null o producirán excepciones.

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) {}
                })
            }
        }
    }
}

Si usa la biblioteca Core Ktx:

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)
        }
    }
}