Estrategia de migración

Si tienes una app existente basada en objetos View, es posible que no quieras volver a escribir toda su IU de una sola vez. Esta página te ayuda a agregar componentes de Compose nuevos a tu app existente. Para comenzar a usar Compose en tu app, consulta Cómo configurar Compose para una app existente.

Jetpack Compose se diseñó con la interoperabilidad de View desde el principio. Esta funcionalidad significa que puedes migrar tu app basada en vistas a Compose sin dejar de compilar funciones nuevas. Para migrar a Compose, recomendamos una migración incremental en la que Compose y las vistas coexistan en la base de código hasta que la app esté completamente en Compose.

Las etapas de la migración de una app basada en vistas a Compose
Figura 1: Las etapas de la migración de una app basada en vistas a Compose

Para migrar tu app a Compose, sigue estos pasos:

  1. Compila pantallas nuevas con Compose.
  2. A medida que compiles funciones, identifica elementos reutilizables y comienza a crear una biblioteca de componentes comunes de la IU.
  3. Reemplaza las funciones existentes de a una pantalla por vez.

Cómo compilar pantallas nuevas con Compose

El uso de Compose para compilar funciones nuevas que abarcan una pantalla completa es la mejor manera de impulsar tu adopción de Compose. Con esta estrategia, puedes agregar funciones y aprovechar los beneficios de Compose sin dejar de satisfacer las necesidades comerciales de tu empresa.

Una pantalla nueva escrita en Compose
Figura 2: Una pantalla nueva escrita en Compose

Cuando usas Compose para compilar pantallas nuevas en tu app existente, sigues trabajando bajo las restricciones de la arquitectura de la app. Si usas fragmentos y el componente de Navigation, tendrás que crear un fragmento nuevo y su contenido estará en Compose.

Para usar Compose en un fragmento, muestra un elemento ComposeView en el método del ciclo de vida onCreateView() de tu fragmento. ComposeView tiene un método setContent() en el que puedes proporcionar una función de componibilidad.

class NewFeatureFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                NewFeatureScreen()
            }
        }
    }
}

Consulta ComposeView en fragmentos para obtener más información.

Agrega funciones nuevas en pantallas existentes

Una pantalla existente con una combinación de objetos de vistas y Compose
Figura 3: Una pantalla existente con una combinación de objetos de vistas y Compose

También puedes usar Compose en una pantalla existente basada en objetos View si la función nueva que agregas forma parte de una pantalla existente. Para ello, agrega un ComposeView a la jerarquía de View, como lo harías con cualquier otra vista.

Por ejemplo, supongamos que deseas agregar una vista secundaria a un LinearLayout. Puedes hacerlo en XML de la siguiente manera:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView
      android:id="@+id/text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />

  <androidx.compose.ui.platform.ComposeView
      android:id="@+id/compose_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
</LinearLayout>

Una vez que la vista haya aumentado, puedes hacer referencia al elemento ComposeView en la jerarquía y llamar a setContent().

Para obtener más información sobre ComposeView, consulta las APIs de interoperabilidad.

Cómo compilar una biblioteca de componentes comunes de la IU

A medida que compiles funciones con Compose, te darás cuenta rápidamente de que terminarás compilando una biblioteca de componentes. Crear una biblioteca de componentes comunes de la IU te permite tener una sola fuente de información para estos componentes en la app y promover la reutilización. Las funciones que compiles pueden depender de esta biblioteca. Esta técnica es especialmente útil si compilas un sistema de diseño personalizado en Compose.

Según el tamaño de tu app, esta biblioteca puede ser un paquete, un módulo o un módulo de biblioteca independientes. Si deseas obtener más información para organizar módulos en tu app, consulta la Guía sobre la modularización de apps para Android.

Cómo reemplazar funciones existentes con Compose

Además de usar Compose para compilar funciones nuevas, te recomendamos que migres de forma gradual las funciones existentes de tu app para aprovechar Compose.

Si tu app es solo para Compose, puedes acelerar el desarrollo y reducir el tamaño del APK y los tiempos de compilación. Consulta Comparar el rendimiento de Compose y View para obtener más información.

Pantallas simples

Los primeros lugares que debes observar cuando migras funciones existentes a Compose son las pantallas simples. Estas pueden ser una pantalla de bienvenida, de confirmación o de configuración en la que los datos que se muestran en la IU son relativamente estáticos.

Toma el siguiente archivo XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView
      android:id="@+id/title_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/title"
      android:textAppearance="?attr/textAppearanceHeadline2" />

  <TextView
      android:id="@+id/subtitle_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/subtitle"
      android:textAppearance="?attr/textAppearanceHeadline6" />

  <TextView
      android:id="@+id/body_text"
      android:layout_width="wrap_content"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:text="@string/body"
      android:textAppearance="?attr/textAppearanceBody1" />

  <Button
      android:id="@+id/confirm_button"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@string/confirm"/>
</LinearLayout>

El archivo en formato XML se puede reescribir en Compose con algunas líneas:

@Composable
fun SimpleScreen() {
    Column(Modifier.fillMaxSize()) {
        Text(
            text = stringResource(R.string.title),
            style = MaterialTheme.typography.headlineMedium
        )
        Text(
            text = stringResource(R.string.subtitle),
            style = MaterialTheme.typography.headlineSmall
        )
        Text(
            text = stringResource(R.string.body),
            style = MaterialTheme.typography.bodyMedium
        )
        Spacer(modifier = Modifier.weight(1f))
        Button(onClick = { /* Handle click */ }, Modifier.fillMaxWidth()) {
            Text(text = stringResource(R.string.confirm))
        }
    }
}

Pantallas combinadas de vistas y Compose

Una pantalla que ya contiene un poco de código de Compose es otra buena opción para migrar por completo a Compose. Según la complejidad de la pantalla, puedes migrarla por completo a Compose o hacerlo parte por parte. Si la pantalla comenzó con Compose en un subárbol de la jerarquía de la IU, continuarás migrando elementos de la IU hasta que toda la pantalla esté en Compose. Este enfoque también se denomina enfoque ascendente.

Enfoque ascendente de la migración de una IU con combinación de vistas y Compose a una en Compose
Figura 4: Enfoque ascendente de la migración de una IU con combinación de vistas y Compose a una en Compose

Cómo quitar fragmentos y el componente Navigation

Puedes migrar a Navigation Compose una vez que puedas quitar todos tus fragmentos y reemplazarlos por los elementos componibles a nivel de la pantalla correspondientes. Los elementos componibles a nivel de la pantalla pueden contener una combinación de contenido de Compose y View, pero todos los destinos de navegación deben ser componibles para habilitar la migración de Navigation Compose. Hasta entonces, debes seguir usando el componente Navigation basado en fragmentos en tu base de código mixta de View y Compose. Consulta Cómo migrar Jetpack Navigation a Navigation Compose para obtener más información.

Recursos adicionales

Revisa los siguientes recursos adicionales si quieres obtener más información para migrar tu app existente basada en vistas a Compose:

Próximos pasos

Ahora que ya conoces la estrategia que puedes usar para migrar tu app existente basada en vistas, explora las APIs de interoperabilidad para obtener más información.