Thursday, 25 February 2010
Canvas.drawLine vs Canvas.drawPath
In Android, if you are in a situation in which you are drawing lots of connected lines (like routes on MapView) try to use "canvas.drawPath". In one of my applications I am drawing nearly 500 routes containing 10.000 points and using "canvas.drawPath" instead of "canvas.drawLine" decreases the drawing time as up to %30.
Friday, 8 January 2010
Android - Baloon Display On Map
I see several posts in Android forums about people asking how to display baloon structures on mapviews. In one of my draft applications I declare a simple solution for this (for source codes and any other issues related to this post, feel free to write me at serkan.dogantekin@gmail.com):
- Define a layout for baloon structure and its "dispatchDraw" draw the baloon itself like:
package com.dogantekin.baloon;
public class BaloonLayout extends LinearLayout {
.......
@Override
protected void dispatchDraw(Canvas canvas) {
Paint panelPaint = new Paint();
panelPaint.setARGB(0, 0, 0, 0);
RectF panelRect = new RectF();
panelRect.set(0,0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(panelRect, 5, 5, panelPaint);
RectF baloonRect = new RectF();
baloonRect.set(0,0, getMeasuredWidth(), 2*(getMeasuredHeight()/3));
panelPaint.setARGB(230, 255, 255, 255);
canvas.drawRoundRect(baloonRect, 10, 10, panelPaint);
Path baloonTip = new Path();
baloonTip.moveTo(5*(getMeasuredWidth()/8), 2*(getMeasuredHeight()/3));
baloonTip.lineTo(getMeasuredWidth()/2, getMeasuredHeight());
baloonTip.lineTo(3*(getMeasuredWidth()/4), 2*(getMeasuredHeight()/3));
canvas.drawPath(baloonTip, panelPaint);
super.dispatchDraw(canvas);
}
}
- Define a layout xml for this layout and add views that will be inside this layout like:
<?xml version="1.0" encoding="utf-8"?>
<com.dogantekin.baloon.BaloonLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/transparent_panel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:paddingTop="5px"
android:paddingRight="5px"
android:paddingBottom="5px">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/note_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="@string/note"
/>
<ImageView
android:id="@+id/close_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="10px"
android:src="@drawable/close"
android:clickable="true"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:paddingLeft="5px"
android:paddingRight="5px"
android:text=""
android:id="@+id/note_text"
android:layout_below="@+id/note_label"
android:layout_centerHorizontal="true"
android:minLines="4"
android:maxLines="4"
android:maxLength="160"
android:textSize="5pt"
/>
</RelativeLayout>
</com.dogantekin.baloon.BaloonLayout>
- In your map activity (where you will have your mapview) create an instance of layout we defined:
LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
noteBaloon = (BaloonLayout) layoutInflater.inflate(R.layout.baloon, null);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200,100);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
noteBaloon.setLayoutParams(layoutParams);
- Now whenever you need to display the baloon, just call mapview's addView method as:
mapView.removeView(noteBaloon);
noteBaloon.setVisibility(View.VISIBLE);
((TextView)noteBaloon.findViewById(R.id.note_text)).setText(msg.getData().getString(HANDLER_MESSAGE_AUTHOR)+"\n"+msg.getData().getString(HANDLER_MESSAGE_NOTE));
mapController.animateTo(noteOverlay.getTapPoint());
mapView.addView(noteBaloon, new MapView.LayoutParams(200,200,noteOverlay.getTapPoint(),MapView.LayoutParams.BOTTOM_CENTER));
mapView.setEnabled(false);
- When you need to remove baloon, just make it invisible:
noteBaloon.setVisibility(View.GONE);
mapView.setEnabled(true);
Below you can find how it is looking:
- Define a layout for baloon structure and its "dispatchDraw" draw the baloon itself like:
package com.dogantekin.baloon;
public class BaloonLayout extends LinearLayout {
.......
@Override
protected void dispatchDraw(Canvas canvas) {
Paint panelPaint = new Paint();
panelPaint.setARGB(0, 0, 0, 0);
RectF panelRect = new RectF();
panelRect.set(0,0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(panelRect, 5, 5, panelPaint);
RectF baloonRect = new RectF();
baloonRect.set(0,0, getMeasuredWidth(), 2*(getMeasuredHeight()/3));
panelPaint.setARGB(230, 255, 255, 255);
canvas.drawRoundRect(baloonRect, 10, 10, panelPaint);
Path baloonTip = new Path();
baloonTip.moveTo(5*(getMeasuredWidth()/8), 2*(getMeasuredHeight()/3));
baloonTip.lineTo(getMeasuredWidth()/2, getMeasuredHeight());
baloonTip.lineTo(3*(getMeasuredWidth()/4), 2*(getMeasuredHeight()/3));
canvas.drawPath(baloonTip, panelPaint);
super.dispatchDraw(canvas);
}
}
- Define a layout xml for this layout and add views that will be inside this layout like:
<?xml version="1.0" encoding="utf-8"?>
<com.dogantekin.baloon.BaloonLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/transparent_panel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:paddingTop="5px"
android:paddingRight="5px"
android:paddingBottom="5px">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/note_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="@string/note"
/>
<ImageView
android:id="@+id/close_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="10px"
android:src="@drawable/close"
android:clickable="true"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:paddingLeft="5px"
android:paddingRight="5px"
android:text=""
android:id="@+id/note_text"
android:layout_below="@+id/note_label"
android:layout_centerHorizontal="true"
android:minLines="4"
android:maxLines="4"
android:maxLength="160"
android:textSize="5pt"
/>
</RelativeLayout>
</com.dogantekin.baloon.BaloonLayout>
- In your map activity (where you will have your mapview) create an instance of layout we defined:
LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
noteBaloon = (BaloonLayout) layoutInflater.inflate(R.layout.baloon, null);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200,100);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
noteBaloon.setLayoutParams(layoutParams);
- Now whenever you need to display the baloon, just call mapview's addView method as:
mapView.removeView(noteBaloon);
noteBaloon.setVisibility(View.VISIBLE);
((TextView)noteBaloon.findViewById(R.id.note_text)).setText(msg.getData().getString(HANDLER_MESSAGE_AUTHOR)+"\n"+msg.getData().getString(HANDLER_MESSAGE_NOTE));
mapController.animateTo(noteOverlay.getTapPoint());
mapView.addView(noteBaloon, new MapView.LayoutParams(200,200,noteOverlay.getTapPoint(),MapView.LayoutParams.BOTTOM_CENTER));
mapView.setEnabled(false);
- When you need to remove baloon, just make it invisible:
noteBaloon.setVisibility(View.GONE);
mapView.setEnabled(true);
Below you can find how it is looking:
- initial mapview
- just make a tap
- touch the close image on baloon
- insert new items in layout xml for richer baloon displays
Tuesday, 29 December 2009
Getting "No server JVM" exception while using STS's Eclipse-Grails plugin
If you are using STS's Grails Eclipse plugin and receive an exception like:
Error: No 'server' JVM at ...
this is mainly because of Eclipse instance's "Installed JREs" setting is pointing a JRE not a JDK. There two possible solutions for this error:
Error: No 'server' JVM at ...
this is mainly because of Eclipse instance's "Installed JREs" setting is pointing a JRE not a JDK. There two possible solutions for this error:
- Select a JDK directory for "Installed JREs" setting
- Copy "/jre/bin/server" directory from a JDK installation to "/jre/bin" directory of a JRE installation
Subscribe to:
Posts (Atom)



