Diseño plegado

Importante

En este artículo se describen la funcionalidad y las instrucciones que se encuentran en versión preliminar pública, por lo que pueden modificarse de forma sustancial antes de que estén disponibles con carácter general. Microsoft no ofrece ninguna garantía, expresa o implícita, con respecto a la información que se ofrece aquí.

Importante

El contenido de esta vista solo estará disponible después de adjuntar la vista raíz de actividades a la ventana. Esto sucede porque la implementación se basa en la biblioteca del Administrador de ventanas y este solo funciona cuando la vista está asociada a la ventana.

El componente FoldableLayout es un diseño personalizado que puede colocar sus elementos secundarios de forma diferente cuando la aplicación se ejecuta en dispositivos plegables. El componente puede dividir la pantalla en dos áreas en función de la posición y orientación de la característica de plegado. Cuando se divide la pantalla, esta puede tener dos contenedores secundarios en paralelo o uno encima del otro.

Diseño de pantalla única Diseño de pantalla doble
Aplicación en una sola pantalla en modo ancho Aplicación distribuida en dos pantallas en modo ancho
Aplicación en una sola pantalla en modo alto Aplicación distribuida en dos pantallas en modo alto

Atributos XML

  • single_screen_layout_id : Recibe el identificador de diseño que se va a mostrar en el modo de pantalla única.
  • dual_screen_start_layout_id : Recibe el identificador de diseño que se va a mostrar en el contenedor de inicio del modo de doble pantalla.
  • dual_screen_end_layout_id : Recibe el identificador de diseño que se va a mostrar en el contenedor de inicio del modo de doble pantalla.

FoldableLayout también tiene la capacidad de crear un único contenedor cuando la aplicación se ejecuta en un dispositivo plegable.

Hemos agregado cuatro nuevos atributos que le ayudarán a crear la interfaz de usuario que desea:

  • dual_portrait_single_layout_id: Recibe el identificador de diseño para el contenedor único vertical doble.
  • is_dual_portrait_single_container: Crea un contenedor único vertical doble vacío.
  • dual_landscape_single_layout_id: Recibe el identificador de diseño para el contenedor único horizontal doble.
  • is_dual_landscape_single_container: crea un único contenedor horizontal doble vacío.

Compatibilidad con smallestScreenSize

Cuando una actividad realiza una transición a un nuevo modo de pantalla, pero no se vuelve a crear porque la marca smallestScreenSize se ha establecido en el archivo de manifiesto, el diseño detectará la nueva configuración y cambiará el tamaño de los contenedores de manera automática, o incluso agregará o quitará el segundo contenedor, en función de la configuración de FoldableLayout.

Vista previa de Android Studio

  • tools_hinge_color: Seleccione el color de la bisagra en la vista previa del diseño.
  • tools_screen_mode: Seleccione el modo de pantalla en la vista previa del diseño.

Si agrega fragmentos dentro de los archivos XML a FoldableLayout, necesitará los siguientes atributos para obtener una vista previa de la interfaz de usuario del fragmento:

  • show_in_single_screen
  • show_in_dual_screen_start
  • show_in_dual_screen_end
  • show_in_dual_portrait_single_container
  • show_in_dual_landscape_single_container

Identificadores de contenedores

Los contenedores tienen los identificadores:

  • first_container_id
  • second_container_id

Independientemente de la orientación de la pantalla o del comportamiento especial establecido en el diseño, si este solo va a mostrar un contenedor, su identificador será first_container_id. Si va a mostrar dos contenedores, también habrá second_container_id.

Por ejemplo:

  • Si la aplicación se encuentra en modo de pantalla única, el identificador del contenedor será first_container_id.
  • Si se realiza una transición al modo de doble pantalla en vertical doble y se ha establecido dual_portrait_single_layout_id o is_dual_portrait_single_container, solo habrá un contenedor en el modo de doble pantalla, y su identificador aún será first_container_id.
  • Cuando se realiza una transición a un modo horizontal doble, pero los atributos dual_landscape_single_layout_id y is_dual_landscape_single_container no están establecidos, se mostrarán ambos contenedores con los identificadores first_container_id y second_container_id.

Creación de FoldableLayout en el código

findViewById<FrameLayout>(R.id.parent).addView(
    FoldableLayout(this, FoldableLayout.Config().apply {
        singleScreenLayoutId = R.layout.single_screen
        dualScreenStartLayoutId = R.layout.dual_screen_start
        dualScreenEndLayoutId = R.layout.dual_screen_end
        dualLandscapeSingleLayoutId = R.layout.single_screen
    })
)

Reemplazar la configuración de FoldableLayout

En el código siguiente se descartará la configuración anterior, se reemplazará por una nueva y se inflará la vista con la nueva configuración.

findViewById<FoldableLayout>(R.id.surface_duo_layout)
    .newConfigCreator()
    .singleScreenLayoutId(R.layout.single_screen)
    .dualScreenStartLayoutId(R.layout.dual_screen_start)
    .dualScreenEndLayoutId(R.layout.dual_screen_end)
    .reInflate()

Actualización de la configuración de FoldableLayout

El código siguiente actualizará la configuración actual con los atributos seleccionados e infle la vista:

findViewById<FoldableLayout>(R.id.surface_duo_layout)
    .updateConfigCreator()
    .dualScreenStartLayoutId(R.layout.dual_screen_start)
    .reInflate()

Uso de los componentes de diseño

Para crear una aplicación, puede usar una actividad o una actividad con fragmentos para administrar la interfaz de usuario. Los fragmentos también se pueden declarar en un archivo de recursos de diseño o se pueden crear directamente en una actividad. Más adelante, hablaremos acerca de cómo los componentes controlan estos casos.

Diagrama del proceso

Uso de una actividad

Aquí vemos cómo funcionan los componentes solo con usar una actividad para controlar la interfaz de usuario.

  1. En primer lugar, tiene que agregar FoldableLayout al archivo *.xml de la actividad.

    <com.microsoft.device.dualscreen.layouts.FoldableLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/enlightened_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        app:single_screen_layout_id="@layout/single_screen_layout"
        app:dual_screen_start_layout_id="@layout/single_screen_layout"
        app:dual_screen_end_layout_id="@layout/dual_screen_end_layout"/>
    
  2. A continuación, se crearán los tres diseños para los diferentes modos de pantalla.

  3. Vincula el diseño a tu actividad.

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }
    

Uso de fragmentos declarados en un archivo de recursos

Aquí se muestra cómo funcionan los componentes con fragmentos que se declaran en los archivos *.xml.

  1. En primer lugar, tiene que agregar FoldableLayout al archivo *.xml de la actividad.

    <com.microsoft.device.dualscreen.layouts.FoldableLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:single_screen_layout_id="@layout/single_screen_layout"
        app:dual_screen_start_layout_id="@layout/dual_screen_start_layout"
        app:dual_screen_end_layout_id="@layout/dual_screen_end_layout" />
    
  2. A continuación, declare los fragmentos de los archivos singlescreenlayout.xml, dualscreenstartlayout.xml y dualscreenendlayout.xml.

    <fragment
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/single_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.microsoft.device.display.samples.contentcontext.MapPointListFragment" />
    
  3. Vincula el diseño a tu actividad.

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }
    

Uso de los fragmentos creados en una actividad

Finalmente, veremos cómo funcionan los componentes con los fragmentos que se agregan mediante getSupportFragmentManager().beginTransaction().

  1. En primer lugar, tiene que agregar FoldableLayout al archivo *.xml de la actividad.

    <com.microsoft.device.dualscreen.layouts.FoldableLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

    Esto crea los contenedores de las vistas pero no se inflará nada en ellos.

  2. Puede acceder a los contenedores de FoldableLayout mediante sus identificadores:

    • first_container_id
    • second_container_id
  3. A continuación, visite la biblioteca de controladores de estado del administrador de fragmentos, ya que los fragmentos necesitan especial atención al trabajar con transiciones del modo de pantalla.

Visualización de enlace

Importante

Use findViewById como se muestra en los fragmentos de código siguientes. No intente usar el enlace de Google View.

Dado que el contenido de FoldableLayout se infla cuando WindowManager tiene información disponible sobre el diseño de la ventana, no se puede recuperar la instancia secundaria y usarla. Para enlazar la vista secundaria, primero es preciso asegurarse de que el contenido de FoldableLayout está listo para usarse. Para ello, debe usar los siguientes métodos:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    private val contentChangedListener = object : FoldableLayout.ContentChangedListener {
        override fun contentChanged(screenMode: ScreenMode?) {
            // Here, you can retrieve the child instance
            val child = binding.foldableLayout.findViewById<View>(R.id.child_view)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }

    override fun onResume() {
        super.onResume()
        binding.foldableLayout.addContentChangedListener(contentChangedListener)
    }

    override fun onPause() {
        super.onPause()
        binding.foldableLayout.removeContentChangedListener(contentChangedListener)
    }
}

donde:

  • FoldableLayout.ContentChangedListener es la devolución de llamada a la que se llamará después de que se infle el contenido de FoldableLayout.

  • FoldableLayout.addContentChangedListener registrará la devolución de llamada de FoldableLayout.ContentChangedListener especificada.

  • foldableLayout.removeContentChangedListener anulará el registro de la devolución de llamada de FoldableLayout.ContentChangedListener especificada.

Importante

Este código se debe agregar dentro de los métodos onResume y onPause de Activity o Fragment para evitar pérdidas de memoria.