Carregar visualizações sob demanda

Às vezes, seu layout exige visualizações complexas que raramente são usadas. Sejam detalhes do item, indicadores de progresso ou mensagens de reversão, você poderá reduzir o uso da memória e acelerar a renderização carregando as visualizações somente quando elas forem necessárias.

Para adiar o carregamento de recursos, é possível adiar o carregamento de recursos quando você tem visualizações complexas que o app precisa no futuro. Para isso, defina um ViewStub para visualizações complexas e raramente usadas.

Definir um ViewStub

A ViewStub é uma visualização leve, sem dimensão e que não desenha nada nem participa do layout. Dessa forma, requer poucos recursos para inflar e sair de uma hierarquia de visualização. Cada ViewStub inclui o atributo android:layout para especificar o layout a ser inflado.

Suponha que você tenha um layout que queira carregar mais tarde na jornada do usuário do 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>

É possível adiar o carregamento usando o ViewStub a seguir. Para que ela mostre ou carregue qualquer coisa, ela precisa mostrar o layout indicado:

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

Carregar o layout da ViewStub

Os snippets de código na seção anterior produzem algo parecido com a Figura 1:

Imagem de uma tela vazia
Figura 1. Estado inicial da tela: o ViewStub está ocultando o layout pesado.

Quando você quiser carregar o layout especificado pela ViewStub, defina-o como visível chamando setVisibility(View.VISIBLE) ou inflate().

O snippet de código a seguir simula um carregamento adiado. A tela é carregada normalmente em Activity e onCreate() e, em seguida, mostra o layout 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. O layout pesado está visível.

Depois de visível ou inflado, o elemento ViewStub não faz mais parte da hierarquia de visualização. Ele é substituído pelo layout inflado, e o ID da visualização raiz desse layout é especificado pelo atributo android:inflatedId do ViewStub. O ID android:id especificado para ViewStub é válido somente até que o layout de ViewStub esteja visível ou inflado.

Para mais informações sobre esse tópico, consulte a postagem do blog Otimizar com stubs.