Thursday, January 17, 2013

Implement bouncing marker for Google Maps Android API v2

bouncing marker

Example to implement a bouncing marker:
  //Make the marker bounce
final Handler handler = new Handler();

final long startTime = SystemClock.uptimeMillis();
final long duration = 2000;

Projection proj = myMap.getProjection();
final LatLng markerLatLng = marker.getPosition();
Point startPoint = proj.toScreenLocation(markerLatLng);
startPoint.offset(0, -100);
final LatLng startLatLng = proj.fromScreenLocation(startPoint);

final Interpolator interpolator = new BounceInterpolator();

handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - startTime;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * markerLatLng.longitude + (1 - t) * startLatLng.longitude;
double lat = t * markerLatLng.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));

if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});




The code in main activity:
package com.example.androidmapsv2;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.graphics.Point;
import android.view.Menu;
import android.view.MenuItem;
import android.view.animation.BounceInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity
implements OnMapLongClickListener, OnMarkerClickListener{

final int RQS_GooglePlayServices = 1;

GoogleMap myMap;

TextView tvLocInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);

FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();

myMap.setMyLocationEnabled(true);

//myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//myMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);

myMap.getUiSettings().setZoomControlsEnabled(true);
myMap.getUiSettings().setCompassEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);

myMap.getUiSettings().setRotateGesturesEnabled(true);
myMap.getUiSettings().setScrollGesturesEnabled(true);
myMap.getUiSettings().setTiltGesturesEnabled(true);
myMap.getUiSettings().setZoomGesturesEnabled(true);
//or myMap.getUiSettings().setAllGesturesEnabled(true);

myMap.setTrafficEnabled(true);

myMap.setOnMapLongClickListener(this);
myMap.setOnMarkerClickListener(this);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}

@Override
protected void onResume() {

super.onResume();

int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}

@Override
public void onMapLongClick(LatLng point) {
tvLocInfo.setText("New marker added@" + point.toString());

BitmapDescriptor bitmapDescriptor
= BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);

myMap.addMarker(new MarkerOptions()
.position(point)
.icon(bitmapDescriptor)
.title(point.toString()));

}

@Override
public boolean onMarkerClick(final Marker marker) {

//Make the marker bounce
final Handler handler = new Handler();

final long startTime = SystemClock.uptimeMillis();
final long duration = 2000;

Projection proj = myMap.getProjection();
final LatLng markerLatLng = marker.getPosition();
Point startPoint = proj.toScreenLocation(markerLatLng);
startPoint.offset(0, -100);
final LatLng startLatLng = proj.fromScreenLocation(startPoint);

final Interpolator interpolator = new BounceInterpolator();

handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - startTime;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * markerLatLng.longitude + (1 - t) * startLatLng.longitude;
double lat = t * markerLatLng.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));

if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});

//return false; //have not consumed the event
return true; //have consumed the event
}

}


download filesDownload the files.

The series:
A simple example using Google Maps Android API v2, step by step.

No comments:

Post a Comment