Clustering on Google Map V2 Part-1

9:31 PM , 4 Comments

Introduction: 

I had done with clustering on Google Map V1. After it is deprecated, i was searching for clustering on Google Map V2. And i found one library Android Maps Extensions. It is working great but depends on your implementation how will you use it in your project.

Drawback : This library use google-play-services.jar and has its own implementation of GoogleMap. Hence if there will any change happen in Map v2 API, takes time to implement that changes in this library.

Screenshots:



Getting Started:

  1. Download zip from above link and import library project.
  2. Import this library to project.
    Note:
    No need to import google play service library project as this library contains it.
  3. Get Map key from API Console.

Map Implementation:

  • Activity extends FragmentActivity
  • FragmentManager fm = getSupportFragmentManager();
  • SupportMapFragment f = (SupportMapFragment) fm.findFragmentById(R.id.map); GoogleMap map = f.getExtendedMap();

Cluster Implementatioin:

map.setClustering(new ClusteringSettings().iconDataProvider(new DemoIconProvider(getResources())));


DemoIconProvider.java:


public class DemoIconProvider implements IconDataProvider {

 private static final int[] res = { R.drawable.m1, R.drawable.m2, R.drawable.m3, R.drawable.m4, R.drawable.m5 };

 private static final int[] forCounts = { 10, 100, 1000, 10000, Integer.MAX_VALUE };

 private Bitmap[] baseBitmaps;

 private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
 private Rect bounds = new Rect();

 private MarkerOptions markerOptions = new MarkerOptions().anchor(0.5f, 0.5f);

 public DemoIconProvider(Resources resources) {
  baseBitmaps = new Bitmap[res.length];
  for (int i = 0; i < res.length; i++) {
   baseBitmaps[i] = BitmapFactory.decodeResource(resources, res[i]);
  }
  paint.setColor(Color.WHITE);
  paint.setTextAlign(Align.CENTER);
  paint.setTextSize(resources.getDimension(R.dimen.text_size));
 }

 @Override
 public MarkerOptions getIconData(int markersCount) {
  Bitmap base;
  int i = 0;
  do {
   base = baseBitmaps[i];
  } while (markersCount >= forCounts[i++]);

  Bitmap bitmap = base.copy(Config.ARGB_8888, true);

  String text = String.valueOf(markersCount);
  paint.getTextBounds(text, 0, text.length(), bounds);
  float x = bitmap.getWidth() / 2.0f;
  float y = (bitmap.getHeight() - bounds.height()) / 2.0f - bounds.top;

  Canvas canvas = new Canvas(bitmap);
  canvas.drawText(text, x, y, paint);

  BitmapDescriptor icon = BitmapDescriptorFactory.fromBitmap(bitmap);
  return markerOptions.icon(icon);
 }
}

TO overcome from drawback, I found one library Clustering on Google Map V2 Part-2 .
It is easy to implement and more customizable.

Download Source code : ClusterMap2


Reference Link: Android Maps Extensions

4 comments:

ListView Animation Tutorial

6:54 PM , 6 Comments


This simple tutorial shows you how to give animation to list view row. There are plenty of animations i covered here. First create anim folder in res folder and create different  XML for  different animation.

List of Animation

  1. Fade IN:
  2. <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="100"
        android:fromAlpha="0.0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toAlpha="1.0" />
    

  3. Hyperspace Out:
  4. <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
       <scale
          android:interpolator="@android:anim/accelerate_decelerate_interpolator"
          android:fromXScale="1.0"
          android:toXScale="1.4"
          android:fromYScale="1.0"
          android:toYScale="0.6"
          android:pivotX="50%"
          android:pivotY="50%"
          android:fillAfter="false"
          android:duration="700" />
       <set
          android:interpolator="@android:anim/accelerate_interpolator"
                    android:startOffset="700">
          <scale
             android:fromXScale="1.4"
             android:toXScale="0.0"
                  android:fromYScale="0.6"
              android:toYScale="0.0"
              android:pivotX="50%"
              android:pivotY="50%"
              android:duration="400" />
          <rotate
             android:fromDegrees="0"
             android:toDegrees="-45"
              android:toYScale="0.0"
              android:pivotX="50%"
              android:pivotY="50%"
              android:duration="400" />
       </set>
    </set>
    

  5. Push Left In:
  6. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromXDelta="100%p" android:toXDelta="0"
             android:duration="300"/>
       <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="300" />
    </set>
    

  7. Push Left Out:
  8. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromXDelta="0" android:toXDelta="-100%p"
            android:duration="300"/>
       <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
            android:duration="300" />
    </set>
    

  9. Push Up In:
  10. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromYDelta="100%p" android:toYDelta="0"
              android:duration="500"/>
       <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
              android:duration="500" />
    </set>
    

  11. Push Up Out:
  12. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromYDelta="0" android:toYDelta="-100%p"
             android:duration="500"/>
       <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
             android:duration="500" />
    </set>
    

  13. Shake:
  14. <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" android:toXDelta="10"
    android:duration="1000" android:interpolator="@anim/cycle" />
    

  15. Cycle:
  16. <cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:cycles="7" />
    

  17. Slide In Top:
  18. <set xmlns:android="http://schemas.android.com/apk/res/android" >
        <translate
            android:duration="1000"
            android:fromYDelta="-100%p"
            android:toYDelta="1" />
    </set>
    

  19. Slide Top to Bottom:
  20. <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
        <translate android:fromYDelta="-100%" android:toXDelta="0"
            android:duration="100" />
        <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="50" />
    </set>
    

  21. Wave Scale:
  22. <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
        <alpha
            android:fromAlpha="0.0"
            android:toAlpha="1.0"
            android:duration="100" />
        <scale
            android:fromXScale="0.5" android:toXScale="1.5"
            android:fromYScale="0.5" android:toYScale="1.5"
            android:pivotX="50%" android:pivotY="50%"
            android:duration="200" />
        <scale
            android:fromXScale="1.5" android:toXScale="1.0"
            android:fromYScale="1.5" android:toYScale="1.0"
            android:pivotX="50%" android:pivotY="50%"
            android:startOffset="200"
            android:duration="100" />
    </set>
    

Create Main activity to create listview and give animation.

MainActivity :
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

 private ListView listview;
 private DisplayMetrics metrics;

 private int mode = 1;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics);

  listview = new ListView(this);
  listview.setFadingEdgeLength(0);
  ArrayList<string> strings = new ArrayList<string>();

  for (int i = 0; i &lt; 300; i++) {
   strings.add("Item:#" + (i + 1));
  }

  MainAdapter mAdapter = new MainAdapter(this, strings, metrics);
  listview.setAdapter(mAdapter);
  setContentView(listview);
 }

 public boolean onCreateOptionsMenu(Menu menu) {
  boolean result = super.onCreateOptionsMenu(menu);
  menu.add(Menu.NONE, 1, 0, "TranslateAnimation1");
  menu.add(Menu.NONE, 2, 0, "TranslateAnimation2");
  menu.add(Menu.NONE, 3, 0, "ScaleAnimation");
  menu.add(Menu.NONE, 4, 0, "fade_in");
  menu.add(Menu.NONE, 5, 0, "hyper_space_in");
  menu.add(Menu.NONE, 6, 0, "hyper_space_out");
  menu.add(Menu.NONE, 7, 0, "wave_scale");
  menu.add(Menu.NONE, 8, 0, "push_left_in");
  menu.add(Menu.NONE, 9, 0, "push_left_out");
  menu.add(Menu.NONE, 10, 0, "push_up_in");
  menu.add(Menu.NONE, 11, 0, "push_up_out");
  menu.add(Menu.NONE, 12, 0, "shake");
  return result;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  mode = item.getItemId();
  return super.onOptionsItemSelected(item);
 }

 public class MainAdapter extends ArrayAdapter<string> {
  private Context context;
  private LayoutInflater mInflater;
  private ArrayList<string> strings;
  private DisplayMetrics metrics_;

  private class Holder {
   public TextView textview;
  }

  public MainAdapter(Context context, ArrayList<string> strings,
    DisplayMetrics metrics) {
   super(context, 0, strings);
   this.context = context;
   this.mInflater = (LayoutInflater) this.context
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   this.strings = strings;
   this.metrics_ = metrics;
  }

  @Override
  public View getView(final int position, View convertView,
    ViewGroup parent) {
   final String str = this.strings.get(position);
   final Holder holder;

   if (convertView == null) {
    convertView = mInflater.inflate(
      android.R.layout.simple_list_item_1, null);
    convertView.setBackgroundColor(0xFF202020);

    holder = new Holder();
    holder.textview = (TextView) convertView
      .findViewById(android.R.id.text1);
    holder.textview.setTextColor(0xFFFFFFFF);
    holder.textview.setBackgroundResource(R.drawable.background);

    convertView.setTag(holder);
   } else {
    holder = (Holder) convertView.getTag();
   }

   holder.textview.setText(str);

   Animation animation = null;

   switch (mode) {
   case 1:
    animation = new TranslateAnimation(metrics_.widthPixels / 2, 0,
      0, 0);
    break;

   case 2:
    animation = new TranslateAnimation(0, 0, metrics_.heightPixels,
      0);
    break;

   case 3:
    animation = new ScaleAnimation((float) 1.0, (float) 1.0,
      (float) 0, (float) 1.0);
    break;

   case 4:
     animation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
    break;
   case 5:
    animation = AnimationUtils.loadAnimation(context, R.anim.hyperspace_in);
    break;
   case 6:
    animation = AnimationUtils.loadAnimation(context, R.anim.hyperspace_out);
    break;
   case 7:
    animation = AnimationUtils.loadAnimation(context, R.anim.wave_scale);
    break;
   case 8:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_left_in);
    break;
   case 9:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_left_out);
    break;
   case 10:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_up_in);
    break;
   case 11:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_up_out);
    break;
   case 12:
    animation = AnimationUtils.loadAnimation(context, R.anim.shake);
    break;
   }

   animation.setDuration(500);
   convertView.startAnimation(animation);
   animation = null;

   return convertView;
  }
 }
}


Download Source code : Listview Animation Demo
Sample Application on Play storeListview Animation Sample Application

6 comments: