Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Add interpolator examples #10067

Merged
merged 1 commit into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.v4.util.LongSparseArray;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.PathInterpolatorCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.Interpolator;

import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
Expand All @@ -24,6 +31,51 @@
public class CameraAnimatorActivity extends AppCompatActivity implements OnMapReadyCallback {

private static final double ANIMATION_DELAY_FACTOR = 1.5;
private static final LatLng START_LAT_LNG = new LatLng(37.787947, -122.407432);

private final LongSparseArray<AnimatorBuilder> animators = new LongSparseArray<AnimatorBuilder>() {
{
put(R.id.menu_action_accelerate_decelerate_interpolator, new AnimatorBuilder() {
@Override
public Animator build() {
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(
createLatLngAnimator(START_LAT_LNG, new LatLng(37.826715, -122.422795)),
obtainExampleInterpolator(new FastOutSlowInInterpolator(), 2500)
);
return animatorSet;
}
});

put(R.id.menu_action_bounce_interpolator, new AnimatorBuilder() {
@Override
public Animator build() {
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(
createLatLngAnimator(START_LAT_LNG, new LatLng(37.787947, -122.407432)),
obtainExampleInterpolator(new BounceInterpolator(), 3750)
);
return animatorSet;
}
});

put(R.id.menu_action_anticipate_overshoot_interpolator, new AnimatorBuilder() {
@Override
public Animator build() {
return obtainExampleInterpolator(new AnticipateOvershootInterpolator(), 2500);
}
});

put(R.id.menu_action_path_interpolator, new AnimatorBuilder() {
@Override
public Animator build() {
return obtainExampleInterpolator(
PathInterpolatorCompat.create(.22f, .68f, 0, 1.71f), 2500);
}
});
}
};


private MapView mapView;
private MapboxMap mapboxMap;
Expand All @@ -32,7 +84,6 @@ public class CameraAnimatorActivity extends AppCompatActivity implements OnMapRe
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);
Expand All @@ -43,27 +94,42 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onMapReady(final MapboxMap map) {
mapboxMap = map;
initFab();
}

private void initFab() {
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
view.setVisibility(View.GONE);
createAnimator(mapboxMap.getCameraPosition()).start();

CameraPosition animatedPosition = new CameraPosition.Builder()
.target(new LatLng(37.789992, -122.402214))
.tilt(60)
.zoom(14.5f)
.bearing(135)
.build();

createExampleAnimator(mapboxMap.getCameraPosition(), animatedPosition).start();
}
});
}

private Animator createAnimator(CameraPosition currentPosition) {
//
// Animator API used for the animation on the FAB
//

private Animator createExampleAnimator(CameraPosition currentPosition, CameraPosition targetPosition) {
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(createLatLngAnimator(currentPosition.target));
animatorSet.play(createZoomAnimator(currentPosition.zoom));
animatorSet.play(createBearingAnimator(currentPosition.bearing));
animatorSet.play(createTiltAnimator(currentPosition.tilt));
animatorSet.play(createLatLngAnimator(currentPosition.target, targetPosition.target));
animatorSet.play(createZoomAnimator(currentPosition.zoom, targetPosition.zoom));
animatorSet.play(createBearingAnimator(currentPosition.bearing, targetPosition.bearing));
animatorSet.play(createTiltAnimator(currentPosition.tilt, targetPosition.tilt));
return animatorSet;
}

private Animator createLatLngAnimator(LatLng currentPosition) {
LatLng target = new LatLng(37.789992, -122.402214);
ValueAnimator latLngAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), currentPosition, target);
private Animator createLatLngAnimator(LatLng currentPosition, LatLng targetPosition) {
ValueAnimator latLngAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), currentPosition, targetPosition);
latLngAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR));
latLngAnimator.setInterpolator(new FastOutSlowInInterpolator());
latLngAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
Expand All @@ -75,8 +141,8 @@ public void onAnimationUpdate(ValueAnimator animation) {
return latLngAnimator;
}

private Animator createZoomAnimator(double currentZoom) {
ValueAnimator zoomAnimator = ValueAnimator.ofFloat((float) currentZoom, 14.5f);
private Animator createZoomAnimator(double currentZoom, double targetZoom) {
ValueAnimator zoomAnimator = ValueAnimator.ofFloat((float) currentZoom, (float) targetZoom);
zoomAnimator.setDuration((long) (2200 * ANIMATION_DELAY_FACTOR));
zoomAnimator.setStartDelay((long) (600 * ANIMATION_DELAY_FACTOR));
zoomAnimator.setInterpolator(new AnticipateOvershootInterpolator());
Expand All @@ -89,8 +155,8 @@ public void onAnimationUpdate(ValueAnimator animation) {
return zoomAnimator;
}

private Animator createBearingAnimator(double currentBearing) {
ValueAnimator bearingAnimator = ValueAnimator.ofFloat((float) currentBearing, 135);
private Animator createBearingAnimator(double currentBearing, double targetBearing) {
ValueAnimator bearingAnimator = ValueAnimator.ofFloat((float) currentBearing, (float) targetBearing);
bearingAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR));
bearingAnimator.setStartDelay((long) (1000 * ANIMATION_DELAY_FACTOR));
bearingAnimator.setInterpolator(new FastOutLinearInInterpolator());
Expand All @@ -103,8 +169,8 @@ public void onAnimationUpdate(ValueAnimator animation) {
return bearingAnimator;
}

private Animator createTiltAnimator(double currentTilt) {
ValueAnimator tiltAnimator = ValueAnimator.ofFloat((float) currentTilt, 60);
private Animator createTiltAnimator(double currentTilt, double targetTilt) {
ValueAnimator tiltAnimator = ValueAnimator.ofFloat((float) currentTilt, (float) targetTilt);
tiltAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR));
tiltAnimator.setStartDelay((long) (1500 * ANIMATION_DELAY_FACTOR));
tiltAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
Expand All @@ -116,20 +182,66 @@ public void onAnimationUpdate(ValueAnimator animation) {
return tiltAnimator;
}

private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
//
// Interpolator examples
//

private final LatLng latLng = new LatLng();
private Animator obtainExampleInterpolator(int menuItemId) {
return animators.get(menuItemId).build();
}

@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
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_animator, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mapboxMap == null) {
return false;
}
findViewById(R.id.fab).setVisibility(View.GONE);
resetCameraPosition();
playAnimation(item.getItemId());
return super.onOptionsItemSelected(item);
}

private void resetCameraPosition() {
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
new CameraPosition.Builder()
.target(START_LAT_LNG)
.zoom(11)
.bearing(0)
.tilt(0)
.build()
));
}

private void playAnimation(int itemId) {
Animator animator = obtainExampleInterpolator(itemId);
if (animator != null) {
animator.start();
}
}

private Animator obtainExampleInterpolator(Interpolator interpolator, long duration) {
ValueAnimator zoomAnimator = ValueAnimator.ofFloat(11.0f, 16.0f);
zoomAnimator.setDuration((long) (duration * ANIMATION_DELAY_FACTOR));
zoomAnimator.setInterpolator(interpolator);
zoomAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mapboxMap.setZoom((Float) animation.getAnimatedValue());
}
});
return zoomAnimator;
}

//
// MapView lifecycle
//

@Override
protected void onStart() {
super.onStart();
Expand Down Expand Up @@ -171,4 +283,25 @@ public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}

/**
* Helper class to evaluate LatLng objects with a ValueAnimator
*/
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;
}
}

interface AnimatorBuilder {
Animator build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
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_cameraTargetLat="37.787947"
app:mapbox_cameraTargetLng="-122.407432"
app:mapbox_cameraZoom="11"
app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"/>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_action_accelerate_decelerate_interpolator"
android:title="@string/menuitem_title_accelerate_decelerate"
app:showAsAction="never"/>
<item
android:id="@+id/menu_action_bounce_interpolator"
android:title="@string/menuitem_title_bounce"
app:showAsAction="never"/>
<item
android:id="@+id/menu_action_anticipate_overshoot_interpolator"
android:title="@string/menuitem_title_anticipate_overshoot"
app:showAsAction="never"/>
<item
android:id="@+id/menu_action_path_interpolator"
android:title="@string/menuitem_title_path"
app:showAsAction="never"/>
</menu>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<string name="menuitem_title_change_location_source_null">Reset location source to null</string>
<string name="menuitem_change_icon_overlap">Toggle icon overlap</string>
<string name="menuitem_change_location">Change location</string>
<string name="menuitem_title_accelerate_decelerate">Accelerate/Decelerate interpolator</string>
<string name="menuitem_title_bounce">Bounce interpolator</string>
<string name="menuitem_title_anticipate_overshoot">Anticipate/Overshoot interpolator</string>
<string name="menuitem_title_path">PathInterpolator interpolator</string>
<string name="button_camera_move">Move</string>
<string name="button_camera_ease">Ease</string>
<string name="button_camera_animate">Animate</string>
Expand Down