Google Maps - Show many markers in a map

别来无恙 提交于 2020-01-30 13:02:16

问题


I have tried for some time now to display multiple markers in a map and I keep running into errors.
I have managed to come up with this code, but i get a crash.

Here is my mapsActivity.java

package com.example.moses.ngongapp;

import android.app.Dialog;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;


import java.util.ArrayList;
import java.util.HashMap;



    public class MapsActivity extends FragmentActivity {

        private GoogleMap googleMap;
        private ArrayList<LatLng> listLatLng;
        private RelativeLayout rlMapLayout;
        HashMap<Marker, LatLngBean> hashMapMarker = new HashMap<Marker, LatLngBean>();

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

            rlMapLayout = (RelativeLayout) findViewById(R.id.rlMapLayout);

            setUpMapIfNeeded();
            setData();

        }

        private void setData() {
            ArrayList<LatLngBean> arrayList = new ArrayList<LatLngBean>();
            LatLngBean bean = new LatLngBean();
            bean.setTitle("Ahmedabad");
            bean.setSnippet("Hello,Ahmedabad");
            bean.setLatitude("23.0300");
            bean.setLongitude("72.5800");
            arrayList.add(bean);

            LatLngBean bean1 = new LatLngBean();
            bean1.setTitle("Surat");
            bean1.setSnippet("Hello,Surat");
            bean1.setLatitude("21.1700");
            bean1.setLongitude("72.8300");
            arrayList.add(bean1);

            LatLngBean bean2 = new LatLngBean();
            bean2.setTitle("Vadodara");
            bean2.setSnippet("Hello,Vadodara");
            bean2.setLatitude("22.3000");
            bean2.setLongitude("73.2000");
            arrayList.add(bean2);

            LoadingGoogleMap(arrayList);
        }

        /**
         * @author Hasmukh Bhadani
         * Set googleMap if require
         */
        private void setUpMapIfNeeded() {
            int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());

            // Google Play Services are not available
            if (status != ConnectionResult.SUCCESS) {
                int requestCode = 10;
                Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
                dialog.show();

            } else if (googleMap == null) {
                ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync((OnMapReadyCallback) this);
                if (googleMap != null) {
                    googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        return;
                    }
                    googleMap.setMyLocationEnabled(true);
                    googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                    googleMap.getUiSettings().setZoomControlsEnabled(true);
                }
            }
        }

        /**
         * @author Hasmukh Bhadani
         * Loading Data to the GoogleMap
         */
// -------------------------Google Map
        void LoadingGoogleMap(ArrayList<LatLngBean> arrayList) {
            if (googleMap != null) {
                googleMap.clear();
                googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    return;
                }
                googleMap.setMyLocationEnabled(true);
                googleMap.getUiSettings().setZoomControlsEnabled(true);

                if (arrayList.size() > 0) {
                    try {
                        listLatLng = new ArrayList<LatLng>();
                        for (int i = 0; i < arrayList.size(); i++) {
                            LatLngBean bean = arrayList.get(i);
                            if (bean.getLatitude().length() > 0 && bean.getLongitude().length() > 0) {
                                double lat = Double.parseDouble(bean.getLatitude());
                                double lon = Double.parseDouble(bean.getLongitude());

                                Marker marker = googleMap.addMarker(new MarkerOptions()
                                        .position(new LatLng(lat, lon))
                                        .title(bean.getTitle())
                                        .snippet(bean.getSnippet())
                                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));

                                //Add Marker to Hashmap
                                hashMapMarker.put(marker, bean);

                                //Set Zoom Level of Map pin
                                LatLng object = new LatLng(lat, lon);
                                listLatLng.add(object);
                            }
                        }
                        SetZoomlevel(listLatLng);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }

                    googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {

                        @Override
                        public void onInfoWindowClick(Marker position) {
                            LatLngBean bean = hashMapMarker.get(position);
                            Toast.makeText(getApplicationContext(), bean.getTitle(), Toast.LENGTH_SHORT).show();

                        }
                    });
                }
            } else {
                Toast.makeText(getApplicationContext(), "Sorry! unable to create maps", Toast.LENGTH_SHORT).show();
            }
        }

        /**
         * @author Hasmukh Bhadani
         * Set Zoom level all pin withing screen on GoogleMap
         */
        public void SetZoomlevel(ArrayList<LatLng> listLatLng) {
            if (listLatLng != null && listLatLng.size() == 1) {
                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(listLatLng.get(0), 10));
            } else if (listLatLng != null && listLatLng.size() > 1) {
                final LatLngBounds.Builder builder = LatLngBounds.builder();
                for (int i = 0; i < listLatLng.size(); i++) {
                    builder.include(listLatLng.get(i));
                }

                final ViewTreeObserver treeObserver = rlMapLayout.getViewTreeObserver();
                treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @SuppressWarnings("deprecation")
                    @Override
                    public void onGlobalLayout() {
                        if (googleMap != null) {
                            googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), findViewById(R.id.map)
                                    .getWidth(), findViewById(R.id.map).getHeight(), 80));
                            rlMapLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        }
                    }
                });

            }
        }
    }

my logcat is here

FATAL EXCEPTION: main
Process: com.example.moses.ngongapp, PID: 28132
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.moses.ngongapp/com.example.moses.ngongapp.MapsActivity}: java.lang.ClassCastException: com.example.moses.ngongapp.MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
    at android.app.ActivityThread.access$800(ActivityThread.java:156)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:211)
    at android.app.ActivityThread.main(ActivityThread.java:5371)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
 Caused by: java.lang.ClassCastException: com.example.moses.ngongapp.MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
    at com.example.moses.ngongapp.MapsActivity.setUpMapIfNeeded(MapsActivity.java:90)
    at com.example.moses.ngongapp.MapsActivity.onCreate(MapsActivity.java:44)

回答1:


@Override
public void onMapReady(GoogleMap map) {
    this.googleMap = map;

    setUpMapIfNeeded();
    setData()
}

Do map related stuff in onMapReady().




回答2:


You can imolement new method like onMapReady and rest of the work regarding inti that method.

((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).
    getMapAsync(new OnMapReadyCallback()

            @Override
          public void onMapReady(GoogleMap map) {
          this.googleMap = map;
          setUpMapIfNeeded();
          setData()
      });



回答3:


Error here

((SupportMapFragment) getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMapAsync((OnMapReadyCallback) this);

Error clearly says "MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback".

So, just implement that interface

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

And implement the corresponding onMapReady method from that interface.

Then, you don't need to cast. Just getMapAsync(MapsActivity.this)

Also don't do any GoogleMap related functions until within or after that method.

Regarding your comments, you have to trace your code as to exactly why if (googleMap != null) { is not being entered. Because the map is null - obviously. But why? Because getMapAsync will "wait" until the map is ready, at which point getMapAsync is called at some undetermined point in the future (hence Async, it runs in the background).

In other words, do not call the setUpMapIfNeeded or setData method in onCreate, but instead only when the map becomes available (from the parameter to the onMapReady method)

@Override
public void onMapReady(GoogleMap map) {
    this.googleMap = map;

    setUpMapIfNeeded();
    setData(); // this calls LoadingGoogleMap() 
}

If the markers still aren't visible, then continue to debug your code. This answer only is intended to address the error mentioned in the question.


By the way, your previous question was already implementing the interface



来源:https://stackoverflow.com/questions/41217159/google-maps-show-many-markers-in-a-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!