Este artículo será útil para aquellos que no hayan utilizado previamente el SDK de Google Maps en su trabajo.
Debajo del cortador, se describen los métodos básicos para trabajar con el mapa, como agregar y administrar marcadores, formas de mover la cámara sobre el mapa, controlar el zoom, construir una ruta y geocodificar. Así como limitaciones y formas de sortearlos.
FuentePara escribir el artículo, me inspiré en mi propia experiencia, que obtuve al escribir una
solicitud de mensajería utilizando mapas de Google en su trabajo. Por lo tanto, todas las capturas de pantalla y una posible mención de la lógica empresarial ocurrirán en el contexto de la construcción de una interfaz de mensajería.
Desafortunadamente, el SDK de Google Maps para Android no le permite cambiar la posición de los botones de control, los llamados Controles de IU, estos incluyen: IndoorLevelPicker: muestra el plano de planta de los edificios, Brújula: la brújula, el botón Mi ubicación: vaya al mapa en la ubicación actual, Barra de herramientas del mapa: botones para construir la ruta y abrir el mapa, así como ZoomControls: aumente y disminuya la escala del mapa.
Usando la barra de herramientas Mapa y ZoomControls como ejemplo, veamos qué dificultades pueden surgir debido a la incapacidad de cambiar la posición de los controles y cómo solucionarlo.
Problemas al visualizar controles de IU desde el SDK (resaltado en naranja) y sus contrapartes personalizadas (resaltado en verde)En este caso, tenemos en la esquina inferior derecha un botón (botón de acción flotante) para ir a la lista de direcciones de pedidos de entrega, en la imagen de la izquierda puede ver que ZoomControls estaba debajo y es prácticamente inaccesible para hacer clic. En la imagen de la derecha, cuando hace clic en el marcador, aparecen botones de la barra de herramientas Mapa, también aparecen debajo del botón para ir a la lista de pedidos.
SoluciónLo primero que debemos hacer es ocultar la visualización de los botones originales. Puede hacer esto anulando el método onMapReady, se llama cuando la tarjeta está lista para usar.
No mostrar botones Control de zoom y no mostrar botones construyen una ruta desde el SDKprivate GoogleMap mMap; private UiSettings uiSettings; @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; uiSettings = mMap.getUiSettings();
Agregamos los botones necesarios al diseño, donde deben estar de acuerdo con nuestro diseño:
Ubicación de botones de control de mapas personalizadosLuego, en el método onCreateView, especifique las acciones que deberían ocurrir cuando se hace clic en nuestros botones:
Controladores para los botones para aumentar y disminuir la escala, así como para construir una ruta private ImageButton imageButtonZoomIn; private ImageButton imageButtonZoomOut; private ImageButton imageButtonRoute; private GoogleMap mMap; @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
La peculiaridad del método
animateCamera es que la escala cambia suavemente y no al instante, y si, por ejemplo, necesita desactivar la animación de un botón de zoom específico cuando se alcanza la escala máxima o mínima, debe redefinir el método
onCameraIdle , que se llama cuando cambia la escala del mapa.
Activando y desactivando los botones de zoom @Override public void onCameraIdle() { if (mMap.getCameraPosition().zoom == mMap.getMinZoomLevel()){
Para realizar cualquier acción con un marcador (excepto arrastrar y soltar), por ejemplo, cree un nuevo pedido, elimine un marcador colocado al azar, vaya a un pedido existente o llame al teléfono como se indica en el pedido, agregue los botones de control apropiados al diseño y registre sus controladores.
Botones de control de marcadorProcesar un clic en un mapa para agregar un marcador y mostrar botones de control personalizados private GoogleMap mMap; private ImageButton imageButtonRoute; @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng latLng) { imageButtonRoute.setVisibility(View.GONE); if (myMarker !=null){
Indicamos qué queremos hacer con el marcador cuando hacemos clic en el botón Agregar orden private ImageButton imageButtonAddMarker; private Marker myMarker; @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { imageButtonAddMarker = view.findViewById(R.id.imageButtonAddMarker); imageButtonAddMarker.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (myMarker !=null && myMarker.getTag()==null) {
Otra característica es que no hay ningún botón en el SDK para eliminar el marcador en la tarjeta. Para hacer esto, también hacemos nuestro propio botón:
Especifique qué queremos hacer con el marcador cuando hacemos clic en el botón Eliminar marcador private ImageButton imageButtonRemoveMarker; private Marker myMarker; @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { imageButtonRemoveMarker = view.findViewById(R.id.imageButtonRemoveMarker); imageButtonRemoveMarker.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (myMarker !=null && myMarker.getTag()==null){
Al hacer clic en el marcador, se abre su título, al hacer clic en el cual también se puede usar para realizar cualquier acción, cuando hago clic en el título de un nuevo marcador, creo un nuevo pedido para la entrega al servicio de mensajería, y en el marcador de un pedido existente, abro información de entrega detallada, incluida una lista bienes.
Establezca la acción al hacer clic en la ventana de información del marcador private GoogleMap mMap; @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() { @Override public void onInfoWindowClick(Marker marker) { if (marker.getTag()==null) {
El proceso de enviar varios marcadores (leer la lista de pedidos) a la tarjeta no es diferente en principio de la salida de un marcador. Un marcador consta de coordenadas (posición), un título (título), un pequeño texto debajo de un título (fragmento) y una etiqueta (setTag); se puede utilizar para identificar muchos marcadores en el mapa.
Varios marcadores de mapaDibujar múltiples marcadores con coordenadas dadas public void drawListMarker(List<InfoMarker> latLngList) { if (latLngList == null || latLngList.size() == 0) { return; }
Algunas palabras sobre geocodificadorSe utiliza un geocodificador para obtener una dirección basada en coordenadas. Al poner un marcador en el mapa y hacer clic en el botón Agregar orden, obtenemos las coordenadas geográficas del punto deseado, es decir latitud y longitud Pero para la conveniencia del usuario, será bueno mostrar la dirección en forma legible para humanos, es decir, por ejemplo, país, ciudad, calle, casa.
El SDK de Google Maps contiene la clase
Geocoder , al llamar a su método
getFromLocation puede obtener una matriz de direcciones en las coordenadas especificadas.
Para no bloquear el subproceso de la interfaz de usuario durante mucho tiempo, especialmente si Internet es lento o inaccesible, mediante llamadas, utilizaremos RxJava:
La dirección del punto resultante en el mapa basada en coordenadas geográficasUsando Java RX para acceder al geocodificador de Google LatLng position = myMarker.getPosition(); Location location = new Location("new"); location.setLatitude(position.latitude); location.setLongitude(position.longitude); LocationRepostiory locationRepostiory = new LocationRepostiory(context, location); locationRepostiory.getLastLocation(). observeOn(SchedulerProvider.getInstance().ui()). subscribeOn(SchedulerProvider.getInstance().computation()). subscribe(locationString -> { if(editTextAddress.length()==0){
El texto de la clase LocationRepostiory en el que ocurre la geocodificación inversa public class LocationRepostiory { private Context context; private Location location; public LocationRepostiory(Context context, Location location) { this.context = context; this.location = location; } public Single<String> getLastLocation() { return Single.create(this::subscribeOnLocation); } private void subscribeOnLocation(SingleEmitter<String> e) { Geocoder geocoder = new Geocoder(context, Locale.getDefault()); String errorMessage = ""; List<Address> addresses = null; try {