在谷歌地图v2 android上绘制多个标记

时间:2013-07-14 10:31:49

标签: android google-maps-markers google-maps-android-api-2

我想在谷歌地图v2上显示多个标记,也可以使用跳转动画点击动画标记。

/**
 * This shows how to place markers on a map.
 */
public class Map extends FragmentActivity implements
                           OnMarkerClickListener, 
                           OnInfoWindowClickListener, 
                           OnMarkerDragListener {

    static LatLng[] GEOPOINTS;
    Map con;
    ArrayList<Article> mArticles;

    DBHelper helper;
    Drawable marker;

    Button search, cancel;
    EditText search_value;
    Button clear_search;
    int activity_flag=0;

    double slat, vlong;

    /**
     * Demonstrates customizing the info window and/or its contents.
     */
    class CustomInfoWindowAdapter implements InfoWindowAdapter {
        private final RadioGroup mOptions;

        // These a both viewgroups containing an ImageView with id "badge" and two TextViews with id
        // "title" and "snippet".
        private final View mWindow;
        private final View mContents;

        CustomInfoWindowAdapter() {
            mWindow = getLayoutInflater().inflate(R.layout.custom_info_window, null);
            mContents = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
            mOptions = (RadioGroup) findViewById(R.id.custom_info_window_options);

        }

        @Override
        public View getInfoWindow(Marker marker) {
            if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_window) {
                // This means that getInfoContents will be called.
                return null;
            }
            render(marker, mWindow);
            return mWindow;
        }

        @Override
        public View getInfoContents(Marker marker) {
            if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_contents) {
                // This means that the default info contents will be used.
                return null;
            }
            render(marker, mContents);
            return mContents;
        }

        private void render(Marker marker, View view) {
            int badge;
            badge = R.drawable.badge_qld;
            ((ImageView) view.findViewById(R.id.badge)).setImageResource(badge);

            String title = marker.getTitle();
            TextView titleUi = ((TextView) view.findViewById(R.id.title));
            if (title != null) {
                // Spannable string allows us to edit the formatting of the text.
                SpannableString titleText = new SpannableString(title);
                titleText.setSpan(new ForegroundColorSpan(Color.RED), 0, titleText.length(), 0);
                titleUi.setText(titleText);
            } else {
                titleUi.setText("");
            }

            String snippet = marker.getSnippet();
            TextView snippetUi = ((TextView) view.findViewById(R.id.snippet));
            if (snippet != null && snippet.length() > 12) {
                SpannableString snippetText = new SpannableString(snippet);
                snippetText.setSpan(new ForegroundColorSpan(Color.MAGENTA), 0, 10, 0);
                snippetText.setSpan(new ForegroundColorSpan(Color.BLUE), 12, snippet.length(), 0);
                snippetUi.setText(snippetText);
            } else {
                snippetUi.setText("");
            }
        }
    }

    private GoogleMap mMap;
    private Marker[] marks;
    private TextView mTopText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.marker_demo);
        con=this;
        mTopText = (TextView) findViewById(R.id.top_text);
       new  loadingTask().execute();

    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map wrap the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getPolarisMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {
        // Hide the zoom controls as the button panel will cover it.
        mMap.getUiSettings().setZoomControlsEnabled(false);

        // Add lots of markers to the map.
        addMarkersToMap();

        // Setting an info window adapter allows us to change the both the contents and look of the
        // info window.
        mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());

        // Set listeners for marker events.  See the bottom of this class for their behavior.
        mMap.setOnMarkerClickListener(this);
        mMap.setOnInfoWindowClickListener(this);
        mMap.setOnMarkerDragListener(this);

        // Pan to see all markers in view.
        // Cannot zoom to bounds until the map has a size.
        final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                @SuppressWarnings("deprecation") // We use the new method when supported
                @SuppressLint("NewApi") // We check which build version we are using.
                @Override
                public void onGlobalLayout() {
                    LatLngBounds bounds = new LatLngBounds.Builder().include(GEOPOINTS[0]).build();
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                        mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                    mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
                }
            });
        }
    }

    private void addMarkersToMap() {
        // Uses a colored icon.

        for (int i=0;i<mArticles.size();i++){
            String latt=mArticles.get(i).latitude.trim().replace(",","");
            String lonn=mArticles.get(i).longitude.trim();

            //set latitude and longitude
            GEOPOINTS[i] = new LatLng(Double.valueOf(latt), Double.valueOf(lonn));

            marks[i] = mMap.addMarker(new MarkerOptions()
                        .position(GEOPOINTS[i])
                        .title(mArticles.get(i).enseigne)
                        .snippet(mArticles.get(i).type)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
        }

    }

    private boolean checkReady() {
        if (mMap == null) {
            Toast.makeText(this, R.string.map_not_ready, Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    /**
     * Called when the Clear button is clicked.
     */
    public void onClearMap(View view) {
        if (!checkReady()) {
            return;
        }
        mMap.clear();
    }

    /**
     * Called when the Reset button is clicked.
     */
    public void onResetMap(View view) {
        if (!checkReady()) {
            return;
        }
        // Clear the map because we don't want duplicates of the markers.
        mMap.clear();
        addMarkersToMap();
    }

    //
    // Marker related listeners.
    //

    @Override
    public boolean onMarkerClick(final Marker marker) {
        // This causes the marker at Perth to bounce into position when it is clicked.

            final Handler handler = new Handler();
            final long start = SystemClock.uptimeMillis();
            Projection proj = mMap.getProjection();
            Point startPoint = proj.toScreenLocation(GEOPOINTS[0]);
            startPoint.offset(0, -100);
            final LatLng startLatLng = proj.fromScreenLocation(startPoint);
            final long duration = 1500;

            final Interpolator interpolator = new BounceInterpolator();

            handler.post(new Runnable() {
                @Override
                public void run() {
                    long elapsed = SystemClock.uptimeMillis() - start;
                    float t = interpolator.getInterpolation((float) elapsed / duration);
                    double lng = t * GEOPOINTS[0].longitude + (1 - t) * startLatLng.longitude;
                    double lat = t * GEOPOINTS[0].latitude + (1 - t) * startLatLng.latitude;
                    marker.setPosition(new LatLng(lat, lng));

                    if (t < 1.0) {
                        // Post again 16ms later.
                        handler.postDelayed(this, 16);
                    }
                }
            });

        // We return false to indicate that we have not consumed the event and that we wish
        // for the default behavior to occur (which is for the camera to move such that the
        // marker is centered and for the marker's info window to open, if it has one).
        return false;
    }

    @Override
    public void onInfoWindowClick(Marker marker) {
        Toast.makeText(getBaseContext(), "Click Info Window", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onMarkerDragStart(Marker marker) {
        mTopText.setText("onMarkerDragStart");
    }

    @Override
    public void onMarkerDragEnd(Marker marker) {
        mTopText.setText("onMarkerDragEnd");
    }

    @Override
    public void onMarkerDrag(Marker marker) {
        mTopText.setText("onMarkerDrag.  Current Position: " + marker.getPosition());
    }

    class loadingTask extends AsyncTask<Void, Void,Void> {

          @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            setUpMapIfNeeded();
        }

        @Override
        protected Void doInBackground(Void... params) {
            helper = DBHelper.getInstance(con);
            mArticles = helper.getArticlesList();
            System.out.println(mArticles.toString());
            return null;
        }
    }

}

但我的日志显示以下错误。

java.lang.RuntimeException: Unable to resume activity 
      {com.example.test/com.example.test.Map}: java.lang.NullPointerException
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2698)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2726)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2212)
    at android.app.ActivityThread.access$600(ActivityThread.java:139)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4899)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at com.example.test.Map.addMarkersToMap(Map.java:233)
    at com.example.test.Map.setUpMap(Map.java:197)
    at com.example.test.Map.setUpMapIfNeeded(Map.java:187)
    at com.example.test.Map.onResume(Map.java:177)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
    at android.app.Activity.performResume(Activity.java:5082)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2688)
    ... 12 more

我有两个问题,第一个是显示多个地理位置,第二个是让每个标记跳转。任何人都可以帮助我。

更新:更改onResume()后的新日志

java.lang.NullPointerException
   at com.example.test.Map$1.onGlobalLayout(Map.java:217)
   at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:646)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1726)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
   at android.view.Choreographer.doCallbacks(Choreographer.java:555)
   at android.view.Choreographer.doFrame(Choreographer.java:525)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
   at android.os.Handler.handleCallback(Handler.java:615)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4899)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
   at dalvik.system.NativeStart.main(Native Method)

第217行

LatLngBounds bounds = new LatLngBounds.Builder().include(GEOPOINTS[0]).build();

1 个答案:

答案 0 :(得分:2)

当您在NullPointerException

中致电mArticles时,setUpMapIfNeeded(); null ,您将获得onResume()

所以 更改

@Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

@Override
    protected void onResume() {
        super.onResume();
        new  loadingTask().execute();
    }

修改:

GEOPOINTS[0] null位于第217行

LatLngBounds bounds = new LatLngBounds.Builder().include(GEOPOINTS[0]).build();

原因

你在private void addMarkersToMap()内遇到问题,你没有初始化GEOPOINTS,所以在for循环之前初始化GEOPOINT ,为此用途:GEOPOINTS=new LatLng[mArticles.size()];

所以看起来应该是这样的:

GEOPOINTS=new LatLng[mArticles.size()];

for (int i=0;i<mArticles.size();i++){

        String latt=mArticles.get(i).latitude.trim().replace(",","");
        String lonn=mArticles.get(i).longitude.trim();

        //set latitude and longitude
        GEOPOINTS[i] = new LatLng(Double.valueOf(latt), Double.valueOf(lonn));