diff options
author | Tobrun Van Nuland <tobrun.van.nuland@gmail.com> | 2017-09-14 16:12:25 +0200 |
---|---|---|
committer | Tobrun <tobrun@mapbox.com> | 2017-09-26 12:06:36 +0200 |
commit | 2f4cc7e4665d6e280bf1770f348fe069ebd928bc (patch) | |
tree | 5478f4dfd433c26cb73050a6653859044f9abb49 /platform | |
parent | 7bcb3232cccbc4e405b12ff0ff772e71d86995b4 (diff) | |
download | qtlocation-mapboxgl-2f4cc7e4665d6e280bf1770f348fe069ebd928bc.tar.gz |
[android] - add API to perform platform side animations
Diffstat (limited to 'platform')
8 files changed, 282 insertions, 4 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 9f6cd7ab5e..12e4c675ee 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -148,7 +148,8 @@ public class MapView extends FrameLayout { addOnMapChangedListener(mapCallback); // callback for focal point invalidation - final FocalPointInvalidator focalPointInvalidator = new FocalPointInvalidator(createFocalPointChangeListener()); + final FocalPointInvalidator focalPointInvalidator = new FocalPointInvalidator(); + focalPointInvalidator.addListener(createFocalPointChangeListener()); // callback for registering touch listeners RegisterTouchListener registerTouchListener = new RegisterTouchListener(); @@ -177,8 +178,11 @@ public class MapView extends FrameLayout { markerViewManager, iconManager, annotations, markers, polygons, polylines); Transform transform = new Transform(nativeMapView, annotationManager.getMarkerViewManager(), trackingSettings, cameraChangeDispatcher); + mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, trackingSettings, myLocationViewSettings, proj, registerTouchListener, annotationManager, cameraChangeDispatcher); + focalPointInvalidator.addListener(mapboxMap.createFocalPointChangeListener()); + mapCallback.attachMapboxMap(mapboxMap); // user input @@ -817,10 +821,10 @@ public class MapView extends FrameLayout { private class FocalPointInvalidator implements FocalPointChangeListener { - private final FocalPointChangeListener[] focalPointChangeListeners; + private final List<FocalPointChangeListener> focalPointChangeListeners = new ArrayList<>(); - FocalPointInvalidator(FocalPointChangeListener... listeners) { - focalPointChangeListeners = listeners; + void addListener(FocalPointChangeListener focalPointChangeListener) { + focalPointChangeListeners.add(focalPointChangeListener); } @Override diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 3afc29f99b..c4b2a1ad4a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -75,6 +75,7 @@ public final class MapboxMap { private final OnRegisterTouchListener onRegisterTouchListener; private MapboxMap.OnFpsChangedListener onFpsChangedListener; + private PointF focalPoint; MapboxMap(NativeMapView map, Transform transform, UiSettings ui, TrackingSettings tracking, MyLocationViewSettings myLocationView, Projection projection, OnRegisterTouchListener listener, @@ -612,6 +613,47 @@ public final class MapboxMap { // /** + * Moves the center of the screen to a latitude and longitude specified by a LatLng object. This centers the + * camera on the LatLng object. + * + * @param latLng Target location to change to + */ + public void setLatLng(@NonNull LatLng latLng) { + nativeMapView.setLatLng(latLng); + } + + /** + * Moves the camera viewpoint to a particular zoom level. + * + * @param zoom Zoom level to change to + */ + public void setZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double zoom) { + if (focalPoint == null) { + focalPoint = new PointF(nativeMapView.getWidth() / 2, nativeMapView.getHeight() / 2); + } + nativeMapView.setZoom(zoom, focalPoint, 0); + } + + /** + * Moves the camera viewpoint angle to a particular angle in degrees. + * + * @param tilt Tilt angle to change to + */ + public void setTilt(@FloatRange(from = MapboxConstants.MINIMUM_TILT, to = MapboxConstants.MAXIMUM_TILT) double tilt) { + nativeMapView.setPitch(tilt, 0); + } + + /** + * Moves the camera viewpoint direction to a particular angle in degrees. + * + * @param bearing Direction angle to change to + */ + public void setBearing(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) + double bearing) { + nativeMapView.setBearing(bearing); + } + + /** * Cancels ongoing animations. * <p> * This invokes the {@link CancelableCallback} for ongoing camera updates. @@ -1986,6 +2028,15 @@ public final class MapboxMap { return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter); } + FocalPointChangeListener createFocalPointChangeListener() { + return new FocalPointChangeListener() { + @Override + public void onFocalPointChanged(PointF pointF) { + focalPoint = pointF; + } + }; + } + // // Interfaces // diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index cefe26b6e5..ec42145a26 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -113,6 +113,17 @@ android:value=".activity.FeatureOverviewActivity"/> </activity> <activity + android:name=".activity.camera.CameraAnimatorActivity" + android:description="@string/description_camera_animator" + android:label="@string/activity_camera_animator"> + <meta-data + android:name="@string/category" + android:value="@string/category_camera"/> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".activity.FeatureOverviewActivity"/> + </activity> + <activity android:name=".activity.camera.CameraPositionActivity" android:description="@string/description_cameraposition" android:label="@string/activity_camera_position"> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java new file mode 100644 index 0000000000..cc44ac9715 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimatorActivity.java @@ -0,0 +1,174 @@ +package com.mapbox.mapboxsdk.testapp.activity.camera; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.TypeEvaluator; +import android.animation.ValueAnimator; +import android.os.Bundle; +import android.support.v4.view.animation.FastOutLinearInInterpolator; +import android.support.v4.view.animation.FastOutSlowInInterpolator; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.view.animation.AnticipateOvershootInterpolator; + +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.testapp.R; + +/** + * Test activity showcasing using Android SDK animators to animate camera position changes. + */ +public class CameraAnimatorActivity extends AppCompatActivity implements OnMapReadyCallback { + + private static final double ANIMATION_DELAY_FACTOR = 1.5; + + private MapView mapView; + private MapboxMap mapboxMap; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_camera_animator); + + mapView = (MapView) findViewById(R.id.mapView); + if (mapView != null) { + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(this); + } + } + + @Override + public void onMapReady(final MapboxMap map) { + mapboxMap = map; + findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + view.setVisibility(View.GONE); + createAnimator(mapboxMap.getCameraPosition()).start(); + } + }); + } + + private Animator createAnimator(CameraPosition currentPosition) { + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.play(createLatLngAnimator(currentPosition.target)); + animatorSet.play(createZoomAnimator(currentPosition.zoom)); + animatorSet.play(createBearingAnimator(currentPosition.bearing)); + animatorSet.play(createTiltAnimator(currentPosition.tilt)); + return animatorSet; + } + + private Animator createLatLngAnimator(LatLng currentPosition) { + LatLng target = new LatLng(37.789992, -122.402214); + ValueAnimator latLngAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), currentPosition, target); + latLngAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR)); + latLngAnimator.setInterpolator(new FastOutSlowInInterpolator()); + latLngAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mapboxMap.setLatLng((LatLng) animation.getAnimatedValue()); + } + }); + return latLngAnimator; + } + + private Animator createZoomAnimator(double currentZoom) { + ValueAnimator zoomAnimator = ValueAnimator.ofFloat((float) currentZoom, 14.5f); + zoomAnimator.setDuration((long) (2200 * ANIMATION_DELAY_FACTOR)); + zoomAnimator.setStartDelay((long) (600 * ANIMATION_DELAY_FACTOR)); + zoomAnimator.setInterpolator(new AnticipateOvershootInterpolator()); + zoomAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mapboxMap.setZoom((Float) animation.getAnimatedValue()); + } + }); + return zoomAnimator; + } + + private Animator createBearingAnimator(double currentBearing) { + ValueAnimator bearingAnimator = ValueAnimator.ofFloat((float) currentBearing, 135); + bearingAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR)); + bearingAnimator.setStartDelay((long) (1000 * ANIMATION_DELAY_FACTOR)); + bearingAnimator.setInterpolator(new FastOutLinearInInterpolator()); + bearingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mapboxMap.setBearing((Float) animation.getAnimatedValue()); + } + }); + return bearingAnimator; + } + + private Animator createTiltAnimator(double currentTilt) { + ValueAnimator tiltAnimator = ValueAnimator.ofFloat((float) currentTilt, 60); + tiltAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR)); + tiltAnimator.setStartDelay((long) (1500 * ANIMATION_DELAY_FACTOR)); + tiltAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mapboxMap.setTilt((Float) animation.getAnimatedValue()); + } + }); + return tiltAnimator; + } + + private static class LatLngEvaluator implements TypeEvaluator<LatLng> { + + private final LatLng latLng = new LatLng(); + + @Override + public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { + latLng.setLatitude(startValue.getLatitude() + + ((endValue.getLatitude() - startValue.getLatitude()) * fraction)); + latLng.setLongitude(startValue.getLongitude() + + ((endValue.getLongitude() - startValue.getLongitude()) * fraction)); + return latLng; + } + } + + @Override + protected void onStart() { + super.onStart(); + mapView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapView.onStop(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_play_arrow_black_24dp.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_play_arrow_black_24dp.xml new file mode 100644 index 0000000000..bf9b895aca --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_play_arrow_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M8,5v14l11,-7z"/> +</vector> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animator.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animator.xml new file mode 100644 index 0000000000..d4933bfb9a --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animator.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.design.widget.CoordinatorLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/coordinator_layout" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.mapbox.mapboxsdk.maps.MapView + android:id="@id/mapView" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:mapbox_cameraTargetLat="37.774913" + app:mapbox_cameraTargetLng="-122.419368" + app:mapbox_cameraZoom="11" + app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"/> + + <android.support.design.widget.FloatingActionButton + android:id="@+id/fab" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="end|bottom" + android:layout_margin="@dimen/fab_margin" + android:src="@drawable/ic_play_arrow_black_24dp" + app:backgroundTint="@android:color/white"/> + +</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml index 976d2c0025..11ffc42a5c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml @@ -60,4 +60,5 @@ <string name="description_animated_image_source">Shows how to animate georeferenced images</string> <string name="description_bottom_sheet">Show 2 MapView on screen with a bottom sheet</string> <string name="description_map_snapshotter">Show a static bitmap taken with the MapSnapshotter</string> + <string name="description_camera_animator">Use Android SDK Animators to animate camera position changes</string> </resources>
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml index da838bf61b..e52851f2db 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml @@ -60,4 +60,5 @@ <string name="activity_animated_image_source">Animated Image Source</string> <string name="activity_bottom_sheet">Bottom sheet</string> <string name="activity_map_snapshotter">Map Snapshotter</string> + <string name="activity_camera_animator">Animator animation</string> </resources>
\ No newline at end of file |