Una delle funzionalità più utili per gli utenti è l'integrazione delle mappe. Nella puntata precedente di questa serie, abbiamo discusso come impostare Google Maps per Android utilizzando il Google Developer Console e come creare un frammento di base di Google Maps. Abbiamo quindi esaminato diversi tipi di indicatori e come disegnare sulla mappa.
In questo tutorial, espanderai ciò che hai appreso nell'ultimo articolo al fine di visualizzare viste in cima a una mappa, ignorare i controlli del selettore di livello interno e aggiungere un componente Street View alle tue applicazioni. Il codice sorgente per questo articolo può essere trovato su GitHub.
Per iniziare, segui i passaggi elencati nell'articolo precedente di questa serie per creare un progetto di base usando a MapFragment
, collegalo a un Attività
, e attiva l'API di Google Maps tramite la Google Developers Console. Per questo tutorial, non è necessario utilizzare le posizioni per le classi Play Services, ma è necessario importare la libreria Play Services di Maps nel tuo build.gradle dipendenze
nodo.
dependencies compile fileTree (dir: 'libs', include: ['* .jar']) compila 'com.android.support:appcompat-v7:23.0.0' compile 'com.google.android.gms: play-services -maps: 7.8.0 '
Una volta fatto, si finisce con uno schermo simile al seguente:
Quindi, è necessario impostare la fotocamera. Per questo tutorial, ci concentreremo su Madison Square Garden a New York City, perché è un ottimo esempio di edificio che utilizza le mappe a livello interno.
Nel onViewCreated
, puoi aggiungere una chiamata al seguente metodo di supporto initCamera
. Potresti ricordare che dobbiamo aspettare fino a quando onViewCreated
lavorare con Google Maps, perché questo è quando sappiamo che l'oggetto della mappa è pronto per l'uso.
private void initCamera () CameraPosition position = CameraPosition.builder () .target (new LatLng (40.7506, -73.9936)) .zoom (18f) .bearing (0.0f) .tilt (0.0f) .build (); getMap (). animateCamera (CameraUpdateFactory.newCameraPosition (posizione), null); getMap (). setMapType (GoogleMap.MAP_TYPE_HYBRID);
Il metodo sopra riportato sposta la fotocamera sul nostro obiettivo e ingrandisce abbastanza vicino da rendere visibile il selettore interno. Noterai che c'è una striscia di numeri sul lato destro dello schermo e una sovrapposizione sulla mappa per ogni piano. Quando selezioni un livello diverso a destra, la planimetria corrente si anima in quella nuova. Questa è la funzione con cui lavorerai più tardi per avere la tua selezione del livello di controllo della visualizzazione.
Successivamente, è necessario implementare le tre interfacce che verranno utilizzate in questo tutorial.
GoogleMap.OnIndoorStateChangeListener
è usato per determinare quando un selettore di livello interno ha cambiato visibilità.SeekBar.OnSeekBarChangeListener
viene utilizzato con una delle nostre sovrapposizioni di visualizzazione per controllare la selezione del livello, anziché utilizzare il set predefinito di pulsanti sulla destra.GoogleMap.OnMapLongClickListener
viene utilizzato in questo esempio per modificare la posizione visualizzata del componente Street View.la classe pubblica MapFragment estende SupportMapFragment implementa GoogleMap.OnIndoorStateChangeListener, GoogleMap.OnMapLongClickListener, SeekBar.OnSeekBarChangeListener
Dopo aver aggiunto i metodi richiesti per queste tre interfacce, è possibile iniziare ad aggiungere viste sulla parte superiore della mappa.
Mentre le funzionalità di base di Google Maps si adattano alla maggior parte delle esigenze, ci saranno momenti in cui desideri aggiungere ulteriori visualizzazioni sulla mappa per poter eseguire azioni. Per questo tutorial, aggiungeremo a SeekBar
e alcuni TextView
oggetti per personalizzare i controlli per il selettore di livello interno.
Inizia creando un nuovo file di layout XML, view_map_overlay.xml. Aggiungere il seguente codice per creare il layout di base che verrà utilizzato sullo schermo.
Una volta completato il file di layout, puoi aggiungerlo come sovrapposizione al frammento delle mappe. Nel onCreateView
, è necessario accedere al ViewGroup
genitore, gonfia il tuo nuovo layout sovrapposto e collegalo al genitore. Questo è anche il punto in cui si salvano i riferimenti a ciascuna vista nell'overlay in modo che possano essere modificati in seguito nella propria app.
@Override public Visualizza onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) ViewGroup parent = (ViewGroup) super.onCreateView (inflater, container, savedInstanceState); Visualizza overlay = inflater.inflate (R.layout.view_map_overlay, parent, false); mIndoorSelector = (SeekBar) overlay.findViewById (R.id.indoor_level_selector); mIndoorMinLevel = (TextView) overlay.findViewById (R.id.indoor_min_level); mIndoorMaxLevel = (TextView) overlay.findViewById (R.id.indoor_max_level); parent.addView (overlay); ritorno genitore;
Quando esegui l'applicazione, dovresti vedere le tue visualizzazioni in cima alla mappa. Tuttavia, vedrai comunque il selettore di livello predefinito, che ingombra la vista.
Per risolvere questo problema, crea un nuovo metodo chiamato initMapIndoorSelector
e chiamalo da onViewCreated
. Tutto ciò che deve fare è impostare i tuoi ascoltatori per il SeekBar
e cambiamenti di livello interno, nonché disabilitare il selettore di livello interno predefinito.
private void initMapIndoorSelector () mIndoorSelector.setOnSeekBarChangeListener (this); getMap (). getUiSettings (). setIndoorLevelPickerEnabled (false); getMap (). setOnIndoorStateChangeListener (this);
Ora che hai la tua vista che si sovrappone alla mappa, devi nasconderla fino a quando non è necessaria. Nel onViewCreated
, chiama un nuovo metodo di supporto chiamato hideFloorLevelSelector
che nasconde tutte le visualizzazioni sovrapposte.
private void hideFloorLevelSelector () mIndoorSelector.setVisibility (View.GONE); mIndoorMaxLevel.setVisibility (View.GONE); mIndoorMinLevel.setVisibility (View.GONE);
Con le tue viste create e nascoste, puoi iniziare ad aggiungere nella logica per far apparire le tue visualizzazioni quando necessario e interagire con la mappa. In precedenza, hai creato il onIndoorBuildingFocused
metodo come parte del GoogleMap.OnIndoorStateChangeListener
. In questo metodo, è necessario salvare un riferimento a qualsiasi edificio sia a fuoco e quindi nascondere o mostrare il SeekBar
controlli quando necessario.
@Override public void onIndoorBuildingFocused () mIndoorBuilding = getMap (). GetFocusedBuilding (); if (mIndoorBuilding == null || mIndoorBuilding.getLevels () == null || mIndoorBuilding.getLevels (). size () <= 1 ) hideFloorLevelSelector(); else showFloorLevelSelector();
Un edificio al coperto si focalizzerà quando l'edificio sarà visibile alla telecamera della mappa e la mappa verrà ingrandita abbastanza. Se tali condizioni non sono più soddisfatte, questo metodo verrà chiamato di nuovo e getMap (). getFocusedBuilding
restituirà a nullo
valore.
showFloorLevelSelector
rende visibili tutte le viste sovrapposte, sposta il SeekBar
al valore selezionato appropriato e imposta le etichette di testo sui valori che rappresentano il nome breve dei piani superiore e inferiore per quell'edificio. Quando recuperi i livelli da un IndoorBuilding
oggetto, il piano inferiore è l'ultimo elemento nell'elenco e il piano superiore è in posizione 0.
private void showFloorLevelSelector () if (mIndoorBuilding == null) return; int numOfLevels = mIndoorBuilding.getLevels (). size (); mIndoorSelector.setMax (numOfLevels - 1); // Bottom floor è l'ultimo elemento nell'elenco, l'ultimo piano è il primo mIndoorMaxLevel.setText (mIndoorBuilding.getLevels (). Get (0) .getShortName ()); mIndoorMinLevel.setText (mIndoorBuilding.getLevels (). get (numOfLevels - 1) .getShortName ()); mIndoorSelector.setProgress (mIndoorBuilding.getActiveLevelIndex ()); mIndoorSelector.setVisibility (View.VISIBLE); mIndoorMaxLevel.setVisibility (View.VISIBLE); mIndoorMinLevel.setVisibility (View.VISIBLE);
Il metodo finale che devi implementare per il tuo selettore di livello interno è onProgressChanged (SeekBar seekBar, int progress, boolean fromUser)
. Quando il SeekBar
la posizione è cambiata, è necessario attivare un nuovo livello sull'edificio attuale. Poiché i livelli sono ordinati dall'alto verso il basso, è necessario attivare il livello in posizione numOfLevels - 1 - progresso
per correlare con la posizione del SeekBar
.
@Override public void onProgressChanged (SeekBar seekBar, int progress, booleano b) if (mIndoorBuilding == null) return; int numOfLevels = mIndoorBuilding.getLevels (). size (); mIndoorBuilding.getLevels (). get (numOfLevels - 1 - progress) .activate ();
Ora che sai come sovrapporre le viste sulla tua mappa e come lavorare con il selettore di livello interno, passiamo a come lavorare con Street View nelle tue app. Proprio come Google Maps, Street View ti consente di utilizzare un frammento o una vista. Per questo esempio, utilizzerai a StreetViewPanoramaView
e sovrapponili al tuo MapFragment
.
Questa vista verrà inizializzata per mostrare la strada accanto al Madison Square Garden e quando si preme a lungo su un'area diversa della mappa, Street View mostrerà le immagini associate alla posizione selezionata. Se selezioni di visualizzare un'area che non è direttamente collegata a un'immagine di Street View, Google sceglierà il più vicino da visualizzare se si trova entro una distanza prestabilita. Se non ci sono immagini Street View nelle vicinanze (ad esempio, seleziona una posizione nel mezzo dell'oceano), Street View mostrerà una schermata nera.
Qualcos'altro da sapere è che puoi averne solo uno StreetViewPanoramaView
o frammento visibile all'utente per volta.
Per iniziare, aggiorna view_map_overlay.xml per aggiungere un StreetViewPanoramaView
.
Quando il tuo file di layout è pronto, vai onCreateView
nel tuo MapFragment
, salva un riferimento alla tua nuova vista e chiama il onCreate
metodo per la vista. È importante che chiami onCreate
, perché il frammento attuale è onCreate
è già stato chiamato prima che questa vista fosse allegata e il componente Street View eseguisse le azioni in onCreate
che sono necessari per l'inizializzazione.
@Override public Visualizza onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) ViewGroup parent = (ViewGroup) super.onCreateView (inflater, container, savedInstanceState); Visualizza overlay = inflater.inflate (R.layout.view_map_overlay, parent, false); mIndoorSelector = (SeekBar) overlay.findViewById (R.id.indoor_level_selector); mIndoorMinLevel = (TextView) overlay.findViewById (R.id.indoor_min_level); mIndoorMaxLevel = (TextView) overlay.findViewById (R.id.indoor_max_level); mStreetViewPanoramaView = (StreetViewPanoramaView) overlay.findViewById (R.id.steet_view_panorama); mStreetViewPanoramaView.onCreate (savedInstanceState); parent.addView (overlay); ritorno genitore;
Avanti, in onViewCreated
, aggiungi un nuovo metodo chiamato initStreetView
. Questo nuovo metodo otterrà in modo asincrono StreetViewPanorama
oggetto quando è pronto e gestisci mostrando la posizione iniziale di Street View. È importante notare questo getStreetViewPanoramaAsync (callback OnStreetViewPanoramaReadyCallback)
può essere chiamato solo dal thread principale.
private void initStreetView () getMap (). setOnMapLongClickListener (this); mStreetViewPanoramaView.getStreetViewPanoramaAsync (new OnStreetViewPanoramaReadyCallback () @Override public void onStreetViewPanoramaReady (StreetViewPanorama panorama) mPanorama = panorama; showStreetView (new LatLng (40.7506, -73.9936)););
Infine, è necessario definire il showStreetView (LatLng latlng)
metodo di supporto mostrato sopra. Questo metodo crea a StreetViewPanoramaCamera
oggetto che consente di modificare l'inclinazione, lo zoom e il rilevamento della videocamera Street View. Per questo esempio, la fotocamera è impostata sui valori predefiniti.
Successivamente, è necessario impostare la posizione della telecamera. In questo esempio, attiviamo anche un'impostazione facoltativa per mostrare i nomi delle strade.
private void showStreetView (LatLng latLng) if (mPanorama == null) return; StreetViewPanoramaCamera.Builder builder = new StreetViewPanoramaCamera.Builder (mPanorama.getPanoramaCamera ()); builder.tilt (0.0f); builder.zoom (0.0f); builder.bearing (0.0f); mPanorama.animateTo (builder.build (), 0); mPanorama.setPosition (latLng, 300); mPanorama.setStreetNamesEnabled (true);
Una volta il tuo showStreetView (LatLng latlng)
il metodo è completo, può anche essere chiamato da onMapLongClick (LatLng latLng)
in modo che tu possa facilmente cambiare quale area viene mostrata.
@Override public void onMapLongClick (LatLng latLng) showStreetView (latLng);
In questo tutorial, hai imparato alcuni modi avanzati per interagire con Google Maps aggiungendo ulteriori visualizzazioni al MapFragment
e hai imparato a controllare il selettore del livello di edificio interno. Abbiamo anche spiegato le nozioni di base sull'aggiunta della funzionalità Street View alla tua applicazione al fine di visualizzare un diverso punto di vista per i tuoi utenti.
Nella prossima puntata di questa serie, imparerai a conoscere il Google Maps Utilities libreria e come usarlo per aggiungere cluster di marker, mappe di calore e altre utili funzionalità per le tue applicazioni.