Поверните MapView в Android

Я пишу приложение для Android, где одна из функций заключается в том, что карта будет вращаться в соответствии с компасом (т. Е. Если телефон указывает на восток, карта будет ориентирована так, чтобы восточная сторона карты была сверху). Предыдущие ответы, которые, как я нашел, были предложены для написания метода onDraw () в mapView, однако api изменил метод на final, чтобы его нельзя было перезаписать. В результате я попытался переписать метод dispatchDraw() следующим образом:

Заметка:

-compass является логическим, если true, поверните представление

-bearing – это переменная с плавающей точкой, которая имеет gradleусы, которые вид должен вращаться

 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(); } 

Благодаря ответам pheelicks и Nikita Koksharov, мне удается включить / выключить поворот карты в соответствии с компасом.

Сначала вам понадобится два внутренних classа MapViewCompassDemo.java, найденных по адресу: Android_SDK_ Tools \ add-ons \ addon-google_apis-google – # \ samples \ MapsDemo \ src \ com \ example \ android \ apis \ view \

 RotateView SmoothCanvas 

Извлеките внутренний class RotateView в RotateView.java и добавьте SmoothCanvas в качестве внутреннего classа RotateView.java вместо MapViewCompassDemo.java

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

maplayout.xml:

       

MapActivity

  /** * Example activity on how to display a google map view rotation with compass * To make it work you need to add: * -  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: * ..\Android\Android SDK Tools\add-ons\addon-google_apis-google-#\samples\MapsDemo\src\com\example\android\apis\view\ * * @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 } } 

Обновление: поворот Google MapView с помощью примера Compass: https://www.dropbox.com/sh/c1encbc2lr63qd9/6C1C4hsrlT

Из документов:

защищенный void dispatchDraw (canvas canvas)

Вызывается рисованием, чтобы нарисовать вид ребенка. Это может быть переопределено производными classами, чтобы получить контроль непосредственно перед тем, как его дети будут нарисованы (но после того, как его собственный вид был нарисован).

Таким образом, переопределение диспетчерских данных не является хорошим, поскольку основное представление карты уже составлено

Одним из решений может быть добавление MapView в качестве дочернего элемента другого CustomView (подclass classа ViewGroup), а затем использование метода dispatchDraw CustomView для поворота MapView (теперь дочернего). Итак, в xml вы бы сделали что-то вроде:

       

Это должно быть примерно так:

 @Override protected void dispatchDraw(Canvas canvas) { canvas.save(Canvas.MATRIX_SAVE_FLAG); if (compass) { // rotate the canvas with the pivot on the center of the screen canvas.rotate(-azimuth, getWidth() * 0.5f, getHeight() * 0.5f); super.dispatchDraw(canvas); canvas.restore(); } } 

Взгляните на примеры MapsDemo в ANDROID_SDK\add-ons\addon-google_apis-google_inc_-7\samples\MapsDemo . В нем есть демо-версия ротации.

 This answer applies to Google Maps api v2. It is possible by registering your application with Sensor Listener for Orientation and get the angle relative to true north inside onSensorChanged and update camera accordingly. Angle can be used for bearing. Following code can be used: Instead of using Sensor.TYPE_ORIENTATION try using getOrinetation api. Sensor.TYPE_ORIENTATION has been deprecated. @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); if (sensorManager != null) sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME); } public void onSensorChanged(SensorEvent event) { float degree = Math.round(event.values[0]); Log.d(TAG, "Degree ---------- " + degree); updateCamera(degree); } private void updateCamera(float bearing) { CameraPosition oldPos = googleMap.getCameraPosition(); CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing) .build(); googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos)); } 
  • Инициализировать MapFragment программно с помощью Maps API v2
  • Как заставить прокси-сервер charles работать с nougat 7 Android?
  • Как исправить android.os.DeadObjectException android X
  • Как отфильтровать тэг в средстве просмотра Eclipse LogCat
  • Получить отпечаток сертификата от приложения android
  • Является ли ondestroy не всегда называется?
  • Как отправить одно сообщение с помощью Firebase Messaging
  • Как добавить разрешение манифеста в приложение для Android?
  • Разрешение на манифест не работает в Android 6
  • Вручную добавление aar с зависимым файлом pom / iml
  • Android-Ошибка: выполнение не выполнено для задачи ': app: transformClassesWithDexForRelease'
  • Давайте будем гением компьютера.