Prácticas recomendadas para la interacción con el mapa de navegación

En esta página, se explican las prácticas recomendadas para interactuar con el mapa de navegación en tu app.

Usa NavigationFragment en lugar de NavigationView siempre que sea posible

NavigationFragment envuelve NavigationView y controla automáticamente sus devoluciones de llamada de ciclo de vida, por lo que no necesitas administrarlas por tu cuenta. Este enfoque es menos propenso a errores y es la forma recomendada de usar la navegación en tu app. Cuando uses NavigationFragment, no invoques los eventos de ciclo de vida de NavigationView directamente.

Si usas NavigationView, usa un orden estricto cuando invoques métodos de ciclo de vida

NavigationView aloja el mapa de Navigation y sigue de cerca los eventos del ciclo de vida como actividades y fragmentos de Android, y realiza acciones específicas cuando se invocan estos eventos del ciclo de vida. NavigationView ejecuta varias inicializaciones en NavigationView#onCreate y NavigationView#onStart, y limpiezas en NavigationView#onStop y NavigationView#onDestroy, así como cuando se procesan otros eventos del ciclo de vida.

Los métodos de ciclo de vida de NavigationView tienen el mismo significado que para las actividades o los fragmentos de Android. Por ejemplo, onCreate de NavigationView se traduce aproximadamente a devoluciones de llamada de ciclo de vida de la actividad o el fragmento de Android, y estas deben invocarlo. Debido a que las devoluciones de llamada de ciclo de vida de NavigationView se basan en las devoluciones de llamada de ciclo de vida de Android y se invocan en el mismo orden, se requiere un orden estricto de estos métodos de NavigationView. De lo contrario, es posible que experimentes fugas de memoria, errores en la IU, problemas con la actualización de la ubicación y otros inconvenientes.

Para obtener más información sobre el ciclo de vida de la actividad de Android, consulta la sección Conceptos del ciclo de vida de la actividad en la documentación para desarrolladores de Android.

En la siguiente tabla, se muestra cuándo se deben invocar otros métodos del ciclo de vida, después de los métodos del ciclo de vida especificados:

Método de ciclo de vida Se invoca en el ciclo de vida de la actividad Se invoca después de qué método de ciclo de vida
onConfigurationChanged() Se invoca cuando la IU está en primer plano y cambia la configuración. Siempre después de onStart()
onTrimMemory() Se invoca cuando una actividad está en segundo plano. Siempre después de onPause()
onSaveInstance() Se invoca antes de que se destruya una actividad. Siempre después de onStop()

No llames a estos métodos de ciclo de vida varias veces sin llamar primero al método de cierre correspondiente. Además, ten en cuenta que, si la app administra algunas de estas devoluciones de llamada del ciclo de vida de Android y se agrega NavigationView al fragmento después de la creación o el inicio, la app debe llamar a los métodos específicos en el orden correcto para inicializar correctamente el SDK de Navigation.

Para obtener orientación adicional sobre el uso de estos métodos, consulta la app de demostración del SDK de Navigation.

Si usas NavigationView, invoca eventos de ciclo de vida desde la actividad o el fragmento, no desde ambos.

Para mantener el orden estricto de los métodos de ciclo de vida, invoca estos eventos desde las devoluciones de llamada de ciclo de vida de la actividad o el fragmento, que reciben estos eventos en orden. Este enfoque garantiza que las apps no necesiten coordinarse entre fragmentos y actividades, y que no generen llamadas duplicadas.

Se actualizó de SupportNavigationFragment a NavigationFragment

A partir de la versión 8.0.0 del SDK de Navigation, NavigationFragment reemplaza a SupportNavigationFragment, que dejó de estar disponible, como el contenedor de fragmentos estándar para la navegación paso a paso y la visualización del mapa.

NavigationFragment mantiene la paridad total de la API con SupportNavigationFragment. Para actualizar tu app, reemplaza SupportNavigationFragment por NavigationFragment en tus archivos de diseño XML y en las importaciones de código fuente. Todas las firmas de métodos y las llamadas a getSupportFragmentManager() siguen siendo idénticas.

Actualiza el XML de diseño

Reemplaza SupportNavigationFragment por NavigationFragment en tus archivos XML de diseño:

Antes (v7.x y versiones anteriores):

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/navigation_fragment"
    android:name="com.google.android.libraries.navigation.SupportNavigationFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Después (v8.0.0 y versiones posteriores):

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/navigation_fragment"
    android:name="com.google.android.libraries.navigation.NavigationFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Si tu app usa FragmentContainerView (recomendado para alojar fragmentos), actualiza el atributo android:name:

<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/navigation_fragment"
    android:name="com.google.android.libraries.navigation.NavigationFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Actualiza el código de la aplicación

Reemplaza las importaciones y las conversiones de clases en tu código Java o Kotlin. Como ambas clases extienden androidx.fragment.app.Fragment, sigue usando getSupportFragmentManager() para buscar el fragmento:

Antes (v7.x y versiones anteriores):

Java

import com.google.android.libraries.navigation.SupportNavigationFragment;

public class MainActivity extends AppCompatActivity {
  private SupportNavigationFragment mNavFragment;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mNavFragment = (SupportNavigationFragment) getSupportFragmentManager()
        .findFragmentById(R.id.navigation_fragment);
  }
}
    

Kotlin

import com.google.android.libraries.navigation.SupportNavigationFragment

class MainActivity : AppCompatActivity() {
  private lateinit var navFragment: SupportNavigationFragment

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

    navFragment = supportFragmentManager
        .findFragmentById(R.id.navigation_fragment) as SupportNavigationFragment
  }
}
    

Después (v8.0.0 y versiones posteriores):

Java

import com.google.android.libraries.navigation.NavigationFragment;

public class MainActivity extends AppCompatActivity {
  private NavigationFragment mNavFragment;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mNavFragment = (NavigationFragment) getSupportFragmentManager()
        .findFragmentById(R.id.navigation_fragment);
  }
}
    

Kotlin

import com.google.android.libraries.navigation.NavigationFragment

class MainActivity : AppCompatActivity() {
  private lateinit var navFragment: NavigationFragment

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

    navFragment = supportFragmentManager
        .findFragmentById(R.id.navigation_fragment) as NavigationFragment
  }
}
    

Paridad de la API

No es necesario que realices ningún otro cambio de comportamiento ni que reestructures tu código. NavigationFragment admite todos los métodos públicos, las interfaces de objetos de escucha y los controles de IU personalizados de SupportNavigationFragment con firmas de métodos idénticas (incluidos getMapAsync(), getNavigator(), setEtaCardEnabled() y setStylingOptions()).