Поверните MapView в Android
Я пишу приложение для Android, где одна из функций заключается в том, что карта будет вращаться в соответствии с компасом (т. Е. Если телефон указывает на восток, карта будет ориентирована так, чтобы восточная сторона карты была сверху). Предыдущие ответы, которые, как я нашел, были предложены для написания метода onDraw () в mapView, однако api изменил метод на final, чтобы его нельзя было перезаписать. В результате я попытался переписать метод dispatchDraw()
следующим образом:
Заметка:
-compass является логическим, если true, поверните представление
- Как установить шрифт для меню «Параметры»?
- REQUEST_DENIED с помощью ключа браузера Google Адреса или приложения?
- размер изображения (drawable-hdpi / ldpi / mdpi / xhdpi)
- Как исправить ошибку android 4.4.2 ClassNotFoundException: не нашел class «com.google.firebase.provider.FirebaseInitProvider» по пути: DexPathList
- Ошибка: выполнение выполнено для задачи ': app: transformClassesWithDexForDebug'
-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(); }
- API 2.3 для Wi-Fi Wi-Fi
- Как выбрать несколько изображений из галереи в Android?
- Intent URI для запуска приложения Gmail
- Лучший способ добавить активность в проект Android в Eclipse?
- логика остановки слежения
- Только макет загрузки, когда звонки с помощью колоды
- Как написать текст над изображением на Android и сохранить его?
- Неправильные координаты из getLocationOnScreen / getLocationInWindow
Благодаря ответам 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)); }