替换默认的Android Maps API v2更改MyLocation图标

27

我想用自己的图像替换Android Maps V2中“我的位置”默认使用的图标。我创建了自己的瓦片提供程序,引入了几张主要为蓝色的地图,因此默认的“我的位置”图标,即小蓝箭头,非常难看到。

以前我会覆盖MyLocationOverlay的draw()方法,但新的API中似乎没有这样的方法。

我还需要图标能够旋转,就像箭头根据你面对的方向而旋转一样。因此,我不能只使用普通的标记。基本上我只需要为该箭头创建一个自定义图像。


你是否已经检查了SDK中Google Map v2的演示,其中演示了如何使用自定义图像添加标记并相应地旋转它。 - GrIsHu
嗨Grishu,我确实看了SDK中的示例。请问演示应用程序的哪个部分特别关注旋转我的位置图标?我似乎找不到它。 - Gyroscope
在 SDK 演示中,检查标记的类,这些标记展示了在地图上添加标记的方法。 - GrIsHu
6个回答

31

我的简单解决方案是禁用谷歌地图的“我的位置”功能,

然后在地图上创建一个带有我的图标的ImageView,

接着在点击事件中捕获ImageView,获取我的位置并在onClick中执行animateCamera。

 this.mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
 this.mGoogleMap.setMyLocationEnabled(true);

.

@Override
public void onClick(final View v) {

    Location location = this.mGoogleMap.getMyLocation();

        if (location != null) {

            LatLng target = new LatLng(location.getLatitude(), location.getLongitude());
            CameraPosition position = this.mGoogleMap.getCameraPosition();

            Builder builder = new CameraPosition.Builder();
            builder.zoom(15);
            builder.target(target);

            this.mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(builder.build()));

          }    
}

26

Google Play服务的最新更新现在允许您使用“平面”标记并旋转它们,这正是我所需要的。下面是我实现的简单版本。我可能还可以对动画进行优化和调整,但目前它已经可以胜任工作了。欢迎提供任何反馈。

Marker mPositionMarker;
GoogleMap mMap;

@Override
public void onLocationChanged(Location location) {

    if (location == null)
        return;

    if (mPositionMarker == null) {

        mPositionMarker = mMap.addMarker(new MarkerOptions()
                .flat(true)
                .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.positionIndicator))
                .anchor(0.5f, 0.5f)
                .position(
                        new LatLng(location.getLatitude(), location
                                .getLongitude())));
    }

    animateMarker(mPositionMarker, location); // Helper method for smooth
                                                // animation

    mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location
            .getLatitude(), location.getLongitude())));

}

public void animateMarker(final Marker marker, final Location location) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final LatLng startLatLng = marker.getPosition();
    final double startRotation = marker.getRotation();
    final long duration = 500;

    final Interpolator interpolator = new LinearInterpolator();

    handler.post(new Runnable() {
        @Override
        public void run() {
            long elapsed = SystemClock.uptimeMillis() - start;
            float t = interpolator.getInterpolation((float) elapsed
                    / duration);

            double lng = t * location.getLongitude() + (1 - t)
                    * startLatLng.longitude;
            double lat = t * location.getLatitude() + (1 - t)
                    * startLatLng.latitude;

            float rotation = (float) (t * location.getBearing() + (1 - t)
                    * startRotation);

            marker.setPosition(new LatLng(lat, lng));
            marker.setRotation(rotation);

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

这是否考虑了轴承? - James Andrew
为什么这行代码会给我一个不兼容类型的错误? final Interpolator interpolator = new LinearInterpolator(); - Keval Patel
可以确认,这个animate方法已经不太好用了。如果你想平滑地移动屏幕,只需要使用map.animateCamera()而不是map.moveCamera。现在对我来说已经足够了。 - Zach

4

截至3.1.36版本,您无法更改图标(我感觉将来会改变,但从API v2改进实施的速度来看,在圣诞节之前不会有太大的改变)。

但是现在您可以使用标记,因为它拥有setIcon函数。

基本上,您必须忘记GoogleMap.setMyLocationEnabled,因为它总是出现在上面。相反,您将创建自己的LocationClient并使用Location中的纬度、经度和方向来更新Marker。此外,添加一个Circle并使用精度来产生类似于默认myLocation可视化效果的效果。


6
来自2019年的问候,它从未被添加到SDK中,但从开发速度来看,在我的未出生的孩子拿到学士学位之前不会准备好。 - Jan Rabe

1

以下是访问位置按钮的代码:

View mv=findViewById(R.id.map);
        View locationButton = ((View) mv.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
        RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
// position on right bottom
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
        rlp.setMargins(0, 180, 180, 0);

1
欢迎来到Stack Overflow!感谢您提供这段代码片段,它可能会提供一些即时帮助。通过展示为什么这是一个好的解决方案,适当的解释将极大地提高其教育价值,并使其对未来具有类似但不完全相同问题的读者更有用。请编辑您的答案以添加解释,并指出适用的限制和假设。 - Toby Speight

1

你无法处理Google地图上的MyLocation按钮的点击事件,但有一个技巧可以让你按照自己的需求获得所需的行为:
首先,在您的layout.xml文件中添加地图和虚拟的MyLocation按钮。
您可以通过RelativeLayout来实现这一点:

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/myLocationButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/mylocation" />
</RelativeLayout>

你可以使用类似于Google地图上看到的“mylocation.png”图标。
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    String s = locationManager.getBestProvider(criteria, false);

    Location location = locationManager.getLastKnownLocation(s);  

调用虚拟的MyLocation按钮的点击事件,在其中添加标记
private GoogleMap googleMap; googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); googleMap.addMarker(new MarkerOptions().icon(YOUR_MODIFIED_ICON).position(latLng).title(TITLE).snippet(SNIPET));
通过这种方式,您可以修改Google地图的默认图标。
同时,您需要设置缩放级别:
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

0

试试这个;我用它来在地图上绘制路线,但我为标记和我的位置设置了图标 声明此以查看您的位置:

    LocationManager locationManager = (LocationManager) 
    getSystemService(LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    String provider = locationManager.getBestProvider(criteria, true);
    Location myLocation= locationManager.getLastKnownLocation(provider);

    longitude = myLocation.getLongitude();
    latitude  = myLocation.getLatitude();
    fromPosition = new LatLng(latitude, longitude);

创建一个类似的函数,我用它来在地图上绘制,但是我在标记上设置了图标和我的位置:
mGoogleMap.clear();
if(response.equalsIgnoreCase("Success"))
{
     ArrayList<LatLng> directionPoint = v2GetRouteDirection.getDirection(document);
     PolylineOptions rectLine = new PolylineOptions().width(7).color(Color.BLUE);

     for (int i = 0; i < directionPoint.size(); i++) {
     rectLine.add(directionPoint.get(i));
     }
     // Adding route on the map
     mGoogleMap.setOnMarkerClickListener(MainActivity.this);
     mGoogleMap.addPolyline(rectLine);
     markerOptions.position(fromPosition);
     markerOptions.draggable(true);
     Marker1 = mGoogleMap.addMarker(new MarkerOptions()
               .position(Estadio)
               .title("Estadio Cuscatlan")
               .snippet("Estadio Cuscatlan")                                                    
               .icon(BitmapDescriptorFactory                                          
               .fromResource(R.drawable.mapmarker))); 
     Marker2 = mGoogleMap.addMarker(new MarkerOptions()
               .position(Metrocentro)
           .title("Metrocentro")
           .snippet("Metrosuelo")
           .icon(BitmapDescriptorFactory
           .fromResource(R.drawable.mapmark
      Marker3 = mGoogleMap.addMarker(new MarkerOptions()
            .position(Mejicanos)
            .title("Mejicanos")
            .snippet("Mejicanos")
            .icon(BitmapDescriptorFactory
            .fromResource(R.drawable.mapmarker)));  
      MarkerMe = mGoogleMap.addMarker(new MarkerOptions()                                             
                        .position(fromPosition) 
                        .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.car64)));
   }
    Dialog.dismiss();
    } 
} 

你能在图片上添加标题吗?.title("Estadio Cuscatlan")=将标题地址设置为图像中的地址,你能做到吗? - Amitsharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接