Cómo cargar vistas on demand

A veces, el diseño requiere vistas complejas que rara vez se usan. Ya sea que se trate de detalles del elemento, indicadores de progreso o mensajes de deshacer, puedes reducir el uso de memoria y acelerar el procesamiento cargando las vistas solo cuando son necesarias.

Puedes diferir los recursos de carga cuando tienes vistas complejas que tu app necesite en el futuro. Para ello, define un ViewStub para las vistas complejas y poco utilizadas.

Define un elemento ViewStub

ViewStub es una vista liviana sin dimensiones que no dibuja nada ni participa en el diseño. Por lo tanto, requiere pocos recursos para aumentarlo y dejarlo en una jerarquía de vistas. Cada ViewStub incluye el atributo android:layout para especificar el diseño que se va a aumentar.

Supongamos que tienes un diseño que deseas cargar más adelante en el recorrido del usuario de tu app:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:src="@drawable/logo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

Puedes posponer la carga con el siguiente ViewStub. Para que muestre o cargue algo, debes hacer que muestre el diseño referido:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ViewStub
    android:id="@+id/stub_import"
    android:inflatedId="@+id/panel_import"
    android:layout="@layout/heavy_layout_we_want_to_postpone"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom" />
</FrameLayout>

Carga el diseño de ViewStub

Los fragmentos de código de la sección anterior producen algo similar a lo que se muestra en la figura 1:

Imagen de una pantalla vacía
Figura 1: Estado inicial de la pantalla: ViewStub oculta el diseño pesado.

Cuando desees cargar el diseño especificado por el ViewStub, configúralo como visible llamando a setVisibility(View.VISIBLE) o a inflate().

En el siguiente fragmento de código, se simula una carga pospuesta. La pantalla se carga como de costumbre en Activity y onCreate(), y luego muestra el diseño de heavy_layout_we_want_to_postpone:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_old_xml)

  Handler(Looper.getMainLooper())
      .postDelayed({
          findViewById<View>(R.id.stub_import).visibility = View.VISIBLE
          
          // Or val importPanel: View = findViewById<ViewStub>(R.id.stub_import).inflate()
      }, 2000)
}

Java

@Override
void onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_old_xml);

  Handler(Looper.getMainLooper())
      .postDelayed({
          findViewById<View>(R.id.stub_import).visibility = View.VISIBLE
          
          // Or val importPanel: View = findViewById<ViewStub>(R.id.stub_import).inflate()
      }, 2000);
}
Figura 2: Se puede ver el diseño pesado.

Una vez visible o aumentado, el elemento ViewStub deja de formar parte de la jerarquía de vistas. Se reemplaza con el diseño aumentado, y el atributo android:inflatedId de ViewStub especifica el ID de la vista raíz de ese diseño. El ID android:id especificado para ViewStub solo es válido hasta que el diseño de ViewStub esté visible o aumente.

Para obtener más información sobre este tema, consulta la entrada de blog Optimiza con stubs.