I am trying to draw a marker on single tap method in android. when i draw the marker it will draw but it will take more time to draw i.e 30-40 milliseconds some times it takes 2-3 seconds. Here is my code for class in which i have draw method.
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();
public MyItemizedOverlay(Drawable pDefaultMarker,
ResourceProxy pResourceProxy) {
super(pDefaultMarker, pResourceProxy);
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean arg2) {
super.draw(canvas, mapView, arg2);
// ---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(p, screenPts);
// ---add the marker---
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_darkblue);
Bitmap bmp1 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_green);
Bitmap bmp2 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_bue);
Bitmap bmp3 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light);
Bitmap bmp4 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light);
Bitmap bmp5 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light);
Bitmap bmp6 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light);
if (count == 1) {
int caller = getIntent().getIntExtra("button", 0);
switch (caller) {
case R.id.btMap:
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton1:
canvas.drawBitmap(bmp1, screenPts.x, screenPts.y - 50, null);
bmp1.recycle();
break;
case R.id.imageButton2:
canvas.drawBitmap(bmp2, screenPts.x, screenPts.y - 50, null);
bmp2.recycle();
break;
case R.id.imageButton3:
canvas.drawBitmap(bmp3, screenPts.x, screenPts.y - 50, null);
bmp3.recycle();
break;
case R.id.imageButton4:
canvas.drawBitmap(bmp4, screenPts.x, screenPts.y - 50, null);
bmp4.recycle();
break;
case R.id.imageButton5:
canvas.drawBitmap(bmp5, screenPts.x, screenPts.y - 50, null);
bmp5.recycle();
break;
case R.id.imageButton6:
canvas.drawBitmap(bmp6, screenPts.x, screenPts.y - 50, null);
bmp6.recycle();
break;
}
}
// Bitmap bmp = BitmapFactory.decodeResource(getResources(),
// R.drawable.pin_annotation_green);
// if (count == 1) {
// canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
// }
}
This background will have simple 1px black lines drawn over the top of it, current code to draw in a grey background. background = new Paint(); background. setColor(bgColor); canvas. drawRect(0, 0, width, height, background);
To draw on a bitmap, use the image control's canvas and attach the mouse-event handlers to the appropriate events in the image control. Typically, you would use region operations (fills, rectangles, polylines, and so on). These are fast and efficient methods of drawing.
Bitmap are close to OS, it is an array of data describing pixels. Canvas is close to what human can see in life like a painting canvas where you can draw a circle or a point, but it doesn't save how this circle pixels will represent in memory (that does bitmap). So, Canvas goes along with Bitmap.
The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).
You should initialize all bitmaps in Constructor. Decoding bitmap takes a long time. You can use a HashMap
(key, value) to store them. Then in onDraw, get the matched bitmap and draw it directly.
For example
public class MyView extends View{
private HashMap<String, Bitmap> mStore = new HashMap<String, Bitmap>();
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
int caller = getIntent().getIntExtra("button", 0);
Bitmap bmp = null;
switch (caller) {
case R.id.btMap:
bmp = mStore.get(R.id.btMap);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
bmp = null;
break;
case R.id.imageButton1:
bmp = mStore.get(R.id.imageButton1);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp1.recycle();
bmp1 = null;
break;
}
super.onDraw(canvas);
}
public void init() {
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_darkblue);
mStore.put(R.id.btMap, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_green);
mStore.put(R.id.imageButton1, bmp);
}
}
Here is what I've done based on your code. You have to check some duplicated resource IDs.
private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();
private HashMap<String, Bitmap> mStore = new HashMap<String, Bitmap>();
public MyItemizedOverlay(Drawable pDefaultMarker,
ResourceProxy pResourceProxy) {
super(pDefaultMarker, pResourceProxy);
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_darkblue);
mStore.put(R.id.btMap, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_green);
mStore.put(R.id.imageButton1, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_bue);
mStore.put(R.id.imageButton2, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light);
mStore.put(R.id.imageButton3, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light); // check it
mStore.put(R.id.imageButton4, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light); // check it
mStore.put(R.id.imageButton5, bmp);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light); // check it
mStore.put(R.id.imageButton6, bmp);
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean arg2) {
super.draw(canvas, mapView, arg2);
// ---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(p, screenPts);
// ---add the marker---
if (count == 1) {
int caller = getIntent().getIntExtra("button", 0);
Bitmap bmp = null;
switch (caller) {
case R.id.btMap:
bmp = mStore.get(R.id.btMap);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton1:
bmp = mStore.get(R.id.imageButton1);
canvas.drawBitmap(bmp1, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton2:
bmp = mStore.get(R.id.imageButton2);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton3:
bmp = mStore.get(R.id.imageButton3);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton4:
bmp = mStore.get(R.id.imageButton4);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton5:
bmp = mStore.get(R.id.imageButton5);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
case R.id.imageButton6:
bmp = mStore.get(R.id.imageButton6);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
bmp.recycle();
break;
}
}
// Bitmap bmp = BitmapFactory.decodeResource(getResources(),
// R.drawable.pin_annotation_green);
// if (count == 1) {
// canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
// }
}
The idea to optimize your code is to perform only the operations necessary for drawing. So you, should remove from your onDraw method :
For instance :
Briefly, minimize the operations during onDraw and you will achieve very fast drawing, around 60 FPS.
You should also consider removing that (ugly) switch and use an hashmap to associate the values of count and the bitmap to draw. An array would even be faster and maybe more appropriate here.
You should remove all BitmapFactory.decodeResource()
calls from your draw()
method. Decode bitmap only once and keep reference to it. Then just call canvas.drawBitmap()
in your draw()
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With