Best practice per l'interazione con la mappa di navigazione

Questa pagina illustra le best practice per interagire con la mappa di navigazione nella tua app.

Se possibile, utilizza NavigationFragment anziché NavigationView

NavigationFragment esegue il wrapping di NavigationView e gestisce automaticamente i relativi callback del ciclo di vita, quindi non devi gestirli manualmente. Questo approccio è meno soggetto a errori ed è il modo consigliato per utilizzare la navigazione nella tua app. Quando utilizzi NavigationFragment, non richiamare direttamente gli eventi del ciclo di vita NavigationView.

Se utilizzi NavigationView, utilizza un ordine rigoroso quando richiami i metodi del ciclo di vita

NavigationView ospita la mappa di navigazione e segue da vicino gli eventi del ciclo di vita come attività e frammenti Android, intraprendendo azioni specifiche quando vengono richiamati questi eventi del ciclo di vita. NavigationView esegue più inizializzazioni su NavigationView#onCreate e NavigationView#onStart e pulizie su NavigationView#onStop e NavigationView#onDestroy, nonché quando vengono elaborati altri eventi del ciclo di vita.

I metodi del ciclo di vita NavigationViewhanno lo stesso significato delle attività o dei frammenti Android. Ad esempio, onCreate di NavigationView si traduce approssimativamente in e deve essere richiamato dai callback del ciclo di vita dell'attività o del fragment Android. Poiché i callback del ciclo di vita di NavigationView sono basati e richiamati nello stesso ordine dei callback del ciclo di vita di Android, è necessario un ordine rigoroso di questi metodi NavigationView. In caso contrario, potresti riscontrare perdite di memoria, errori dell'interfaccia utente, mancato aggiornamento della posizione e altri problemi.

Per saperne di più sul ciclo di vita dell'attività Android, consulta la sezione Concetti relativi al ciclo di vita dell'attività nella documentazione per gli sviluppatori Android.

La tabella seguente mostra quando devono essere richiamati altri metodi del ciclo di vita, dopo metodi del ciclo di vita specificati:

Metodo del ciclo di vita Richiamato in quale punto del ciclo di vita dell'attività Richiamato dopo quale metodo del ciclo di vita
onConfigurationChanged() Viene richiamato quando la UI è in primo piano e la configurazione cambia. Sempre dopo onStart()
onTrimMemory() Richiamato quando un'attività è in background. Sempre dopo onPause()
onSaveInstance() Richiamato prima che un'attività venga eliminata. Sempre dopo onStop()

Non chiamare più volte questi metodi del ciclo di vita senza chiamare prima il metodo di chiusura corrispondente. Inoltre, tieni presente che se alcuni di questi callback del ciclo di vita di Android vengono gestiti dall'app stessa e l'NavigationView viene aggiunto al frammento dopo la creazione o l'avvio, l'app deve chiamare i metodi specifici nell'ordine corretto per inizializzare correttamente l'SDK Navigation.

Per ulteriori indicazioni sull'utilizzo di questi metodi, consulta l'app demo dell'SDK Navigation.

Se utilizzi NavigationView, richiama gli eventi del ciclo di vita dall'attività o dal fragment, non da entrambi.

Per mantenere l'ordine rigoroso dei metodi del ciclo di vita, richiama questi eventi dai callback del ciclo di vita dell'attività o del frammento, che li ricevono in ordine. Questo approccio garantisce che le app non debbano coordinarsi tra frammenti e attività e causare chiamate duplicate.

Aggiornamento da SupportNavigationFragment a NavigationFragment

A partire da Navigation SDK v8.0.0, NavigationFragment sostituisce SupportNavigationFragment deprecato come contenitore di frammenti standard per la navigazione passo passo e la visualizzazione della mappa.

NavigationFragment mantiene la piena parità dell'API con SupportNavigationFragment. Per aggiornare l'app, sostituisci SupportNavigationFragment con NavigationFragment nei file di layout XML e nelle importazioni del codice sorgente. Tutte le firme dei metodi e le chiamate getSupportFragmentManager() rimangono identiche.

Aggiorna il file XML del layout

Sostituisci SupportNavigationFragment con NavigationFragment nei file XML del layout:

Prima (v7.x e versioni precedenti):

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

Dopo (v8.0.0+):

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

Se la tua app utilizza FragmentContainerView (opzione consigliata per l'hosting di fragment), aggiorna l'attributo 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" />

Aggiorna il codice dell'applicazione

Sostituisci le importazioni e i cast di classe nel codice Java o Kotlin. Poiché entrambe le classi estendono androidx.fragment.app.Fragment, continua a utilizzare getSupportFragmentManager() per cercare il frammento:

Prima (v7.x e versioni precedenti):

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

Dopo (v8.0.0+):

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

Parità delle API

Non è necessario apportare altre modifiche al comportamento o ristrutturare il codice. NavigationFragment supporta tutti i metodi pubblici, le interfacce listener e i controlli UI personalizzati di SupportNavigationFragment con firme di metodo identiche (inclusi getMapAsync(), getNavigator(), setEtaCardEnabled() e setStylingOptions()).