Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
704 views
in Technique[技术] by (71.8m points)

google maps - Rotate MapView in Android

I am writing an Android app where one of the features is that the map will rotate according to the compass (i.e. if the phone is pointing east, the map will be oriented so that the east side of the map is on top). Previous answers that I have found suggested over writing the onDraw() method in mapView, however, the api changed the method to final so it cannot be overwritten. As a result I have tried to overwrite the dispatchDraw() method like so:

Note:

-compass is a boolean that if true, rotate the view

-bearing is a float variable that has the degrees that the view should rotate

protected void dispatchDraw(Canvas canvas) {
    canvas.save();
         if (compass) {
             final float w = this.getWidth();
             final float h = this.getHeight();

             final float scaleFactor = (float)(Math.sqrt(h * h + w * w) / Math.min(w, h));

             final float centerX = w / 2.0f;
             final float centerY = h / 2.0f;

             canvas.rotate(bearing, centerX, centerY);
             canvas.scale(scaleFactor, scaleFactor, centerX, centerY);

         }
         super.dispatchDraw(canvas);
         canvas.restore();
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to pheelicks and Nikita Koksharov answers, I manage to turn on/off the rotation of a mapview according to the compass.

First you will need the two inner class of MapViewCompassDemo.java found at: Android_SDK_ Toolsadd-onsaddon-google_apis-google-#samplesMapsDemosrccomexampleandroidapisview

RotateView
SmoothCanvas

Extract the inner class RotateView to RotateView.java and add SmoothCanvas as a inner class of RotateView.java instead of MapViewCompassDemo.java

public class RotateView extends ViewGroup implements SensorListener {
...
   static final class SmoothCanvas extends Canvas {
...
   }//end SmoothCanvas 
}//end RotateView 

maplayout.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map_layout_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/rotating_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.google.android.maps.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:apiKey="##### YOUR MAP KEY HERE ######"
        android:clickable="true" />
</LinearLayout>

<ToggleButton
    android:id="@+id/button_compass"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:onClick="onClick"
    android:textOff="compass off"
    android:textOn="compass on" />

</RelativeLayout>

The MapActivity

 /**
 * Example activity on how to display a google map view rotation with compass
 * To make it work you need to add:
 *  - <uses-library android:name="com.google.android.maps" /> in the manifest.xml file
 *  - Your Android Maps API Key from https://developers.google.com/android/maps-api- signup
 *  - Set the project build target to "Google APIs"
 *  - Extract/Add the two inner classes RotateView and SmoothCanvas of MapViewCompassDemo.java found at: 
 * ..AndroidAndroid SDK Toolsadd-onsaddon-google_apis-google-#samplesMapsDemosrccomexampleandroidapisview
 * 
 * @author hsigmond - touchboarder.com - 
 *
 */
public class MapViewRotationWithCompass extends MapActivity {

private MapView mMapView;
private MyLocationOverlay mMyLocationOverlay = null;
private boolean mModeCompass = false;
private SensorManager mSensorManager;
private LinearLayout mRotateViewContainer;
private RotateView mRotateView;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.maplayout);
    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    mRotateViewContainer = (LinearLayout) findViewById(R.id.rotating_view);
    mRotateView = new RotateView(this);

    // Sign Up for the Android Maps API at:
    // https://developers.google.com/android/maps-api-signup
    // Add the Android Maps API key to the MapView in the maplayout.xml file 
    mMapView = (MapView) findViewById(R.id.map_view);
    mMyLocationOverlay = new MyLocationOverlay(this, mMapView);     

}

@SuppressWarnings("deprecation")
public void onClick(View v) {

    switch (v.getId()) {

    case R.id.button_compass:
        if (mMyLocationOverlay.isCompassEnabled()) {
            mSensorManager.unregisterListener(mRotateView);
            mRotateView.removeAllViews();
            mRotateViewContainer.removeAllViews();
            mRotateViewContainer.addView(mMapView);
            mMyLocationOverlay.disableCompass();
            mModeCompass = false;
        } else {
            mRotateViewContainer.removeAllViews();
            mRotateView.removeAllViews();
            mRotateView.addView(mMapView);
            mRotateViewContainer.addView(mRotateView);
            mMapView.setClickable(true);
            mSensorManager.registerListener(mRotateView,
                    SensorManager.SENSOR_ORIENTATION,
                    SensorManager.SENSOR_DELAY_UI);
            mMyLocationOverlay.enableCompass();
            mModeCompass = true;
        }
        break;
    }
}

@SuppressWarnings("deprecation")
@Override
public void onResume() {
    super.onResume();
    if (mModeCompass) {
        mMyLocationOverlay.enableCompass();
        mSensorManager.registerListener(mRotateView,
                SensorManager.SENSOR_ORIENTATION,
                SensorManager.SENSOR_DELAY_UI);
    }
}

@Override
public void onPause() {
    super.onPause();
    mMyLocationOverlay.disableCompass();
}

@SuppressWarnings("deprecation")
@Override
protected void onStop() {
    mSensorManager.unregisterListener(mRotateView);
    super.onStop();
}

@Override
protected boolean isRouteDisplayed() {
    return (false);// Don't display a route
}

}

Update: Rotating Google MapView with Compass Example Project: https://www.dropbox.com/sh/c1encbc2lr63qd9/6C1C4hsrlT


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...