Strange drawing artefact using custom drawable with MapView - android

I'm trying to add my own drawable and use it in a series of overlays on a MapView. The drawable is basically a rounded box with a black outline and a number in the middle.
I have managed to achieve this using the code below, however there is what looks like a flag to the left of my box, which I certainly don't think I have drawn - so I'm wondering what it can be.
This is an example of the image:
Edit - this is what happens if a circle is drawn:
My code is below:
Custom Drawable:
public class BikeDrawable extends Drawable {
int colour;
String bikes;
public BikeDrawable (int bikes){
this.bikes = Integer.toString(bikes);
if (bikes < 4) {
colour = Color.RED;
}
else if (bikes > 3 && bikes < 9){
colour = Color.argb(244, 255, 127, 42);
}
else {
colour = Color.GREEN;
}
}
#Override
public void draw(Canvas canvas) {
Paint rectanglePaint = new Paint();
rectanglePaint.setColor(colour);
rectanglePaint.setStyle(Style.FILL);
RectF rectangle = new RectF(0.0f, 0.0f, 20.0f, 20.0f);
Paint strokepaint = new Paint();
strokepaint.setStyle(Paint.Style.STROKE);
strokepaint.setStrokeWidth(2);
strokepaint.setARGB(255, 0, 0, 0);
canvas.drawRoundRect(rectangle, 4.0f, 4.0f, rectanglePaint);
canvas.drawRoundRect(rectangle, 4.0f, 4.0f, strokepaint);
Paint textpaint = new Paint();
textpaint.setARGB(255, 0, 0, 0);
textpaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(bikes, 10, 14, textpaint);
}
#Override
public int getOpacity() {
return 0;
}
#Override
public void setAlpha(int alpha) {
}
#Override
public void setColorFilter(ColorFilter cf) {
}
}
Use in MapView:
bikeOverlay = new PointsOverlay(start_icon);
BikeDrawable start_1_drawable = new BikeDrawable (start_1.capacity);
OverlayItem start_1_overlayitem = new OverlayItem(new GeoPoint(start_1.lat,start_1.lon), null, null);
start_1_overlayitem.setMarker(start_1_drawable);
mapOverlays.add(bikeOverlay);
bikeOverlay.addOverlay(start_1_overlayitem);
Does anyone have any idea what is going on here? Is it an artefact from OverlayItem?

This was achieved by overriding the draw() method of the PointsOverlay as follows:
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow)
{
if(!shadow)
{
super.draw(canvas, mapView, false);
}
}
Thanks to etteyafed - I would have credited you with the points if you had answered, but I wanted to close this off.

Related

I cant seem to find whats wrong with this code i just started but i wont draw the canvas

Here is the Code:
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
drawUPS( canvas);
drawFPS( canvas);
}
public void drawUPS(#NonNull Canvas canvas){
String averageUPS = Double.toString(gameloop.getAverageUPS());
Paint textPaint = new Paint();
int color = ContextCompat.getColor(context, R.color.white);
canvas.drawText("UPS" + averageUPS, 100, 100,textPaint);
textPaint.setColor(color);
textPaint.setTextSize(50);
}
public void drawFPS(#NonNull Canvas canvas){
String averageFPS = Double.toString(gameloop.getAverageFPS());
Paint paint = new Paint();
int color = ContextCompat.getColor(context, R.color.white);
paint.setColor(color);
paint.setTextSize(50);
canvas.drawText("FPS" + averageFPS, 100, 200,paint);
}
I did everything that is necessary for the canvas to be drawn but it just wont and i dont find any solutions anywhere

How to make a balll move over a rectangle in a specified area in android

İn my application İ want to make a ball move inside a specific area (rectangle). till now the ball moves all around the screen in the background area under the rectangle. İ tried changing the coordinates several time but it didnt work. can anyone help me make the ball move within the rectangle?
class DrawView extends View {
int x,y,x1,y1;
int a=431,b=641, a1=54,b1=54;
int sayac=0;
Canvas can;
Paint paint = new Paint();
Rect r = new Rect(60, 60, 400, 610);
Paint por= new Paint();
// Font bold;
public DrawView(Context context) {
super(context);
paint.setColor(Color.RED);
}
private void update() {
if(a>605){x=-(int)(Math.random()*7+5); }
if(a<55){x=(int)(Math.random()*7+5); }
if(b>395){y=-(int)(Math.random()*7+5); }
if(b<55){y=(int)(Math.random()*7+5); }
if(a1>605){x1=-(int)(Math.random()*7+5); }
if(a1<55){x1=(int)(Math.random()*7+5); }
if(b1>395){y1=-(int)(Math.random()*7+5); }
if(b1<55){y1=(int)(Math.random()*7+5); }
a+=x;
b+=y;
a1+=x1;
b1+=y1;
}
#Override
protected void onDraw(Canvas canvas) {
paint.setTextSize(20);
paint.setColor(Color.YELLOW);
canvas.drawCircle(a, b, 50, paint);
paint.setColor(Color.BLUE);
canvas.drawText("Pamukcu", a-41, b+7, paint);
/* paint.setColor(Color.RED);
canvas.drawLine(40, 40, 600, 40, paint);
paint.setStrokeWidth(10f);
canvas.drawLine(40, 600, 600, 600, paint);
canvas.drawLine(40, 40, 40, 600, paint);
canvas.drawLine(600, 40, 40, 600, paint);
*/
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.MAGENTA);
canvas.drawRect(r, paint);
update();
try{
Thread.sleep(1);
}catch(InterruptedException e){ }
invalidate();
private void update() {
if(a>605){x=-(int)(Math.random()*7+5); }
if(a<55){x=(int)(Math.random()*7+5); }
if(b>395){y=-(int)(Math.random()*7+5); }
if(b<55){y=(int)(Math.random()*7+5); }
if(a1>605){x1=-(int)(Math.random()*7+5); }
if(a1<55){x1=(int)(Math.random()*7+5); }
if(b1>395){y1=-(int)(Math.random()*7+5); }
if(b1<55){y1=(int)(Math.random()*7+5); }
a+=x;
b+=y;
a1+=x1;
b1+=y1;
}
#Override
protected void onDraw(Canvas canvas) {
paint.setTextSize(20);
paint.setColor(Color.YELLOW);
canvas.drawCircle(a, b, 50, paint);
paint.setColor(Color.BLUE);
canvas.drawText("Ball", a-41, b+7, paint);
If you want that the ball can only move inside a rectangle than you can do it like this:
int rectangleX = 100;
int rectangleY = 100;
int rectangleWidht = 200;
int rectangleHeight = 300;
private void KeepBallInsideRectangle() {
if (ballX < rectanlgeX) ballX = rectangleX;
if (ballX > rectangleX+rectangleWidth) ballX = rectangleX+rectangleWidth;
if (ballY < rectanlgeY) ballY = rectangleY;
if (ballY > rectangleY+rectanglHeight) ballY = rectangleY+rectangleHeight;
}
You just check if the balls position is outside of the rectangle and then set its position to the border of the rectangle.

android split the circle without taking the origin into consideration

I'm trying to split the circle into something of this sort:
http://i.stack.imgur.com/hNg3E.png
I want to color the major arc part of the circle with transparent color and minor arc of the circle with black color. Here is what I have tried, but unable to reach the final goal:
public class SplitCircleDrawable extends Drawable {
private final Bitmap mBitmap;
private final Paint mPaint;
private final Paint mBackGroundPaint,mTransparentPaint;
private final RectF mRectF;
private final int mBitmapWidth;
private final int mBitmapHeight;
private Context mCtx;
public SplitCircleDrawable(Bitmap bitmap, Context mContext) {
mCtx = mContext;
mBitmap=bitmap;
mRectF = new RectF();
mPaint = new Paint();
mBackGroundPaint = new Paint();
mTransparentPaint=new Paint();
mBackGroundPaint.setColor(0x97021829);
mTransparentPaint.setColor(Color.TRANSPARENT);
mBackGroundPaint.setDither(true);
mBackGroundPaint.setAntiAlias(true);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
// NOTE: we assume bitmap is properly scaled to current density
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
}
#Override
public void draw(Canvas canvas) {
canvas.drawOval(mRectF, mPaint);
canvas.drawArc(mRectF, 0, 180, false, mBackGroundPaint);
// canvas.drawArc(mRectF, 0, 45, true, mTransparentPaint);
// canvas.drawArc(mRectF, 45, 135, true, mBackGroundPaint);
// canvas.drawArc(mRectF, 135, 180, true, mTransparentPaint);
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRectF.set(bounds);
}
#Override
public void setAlpha(int alpha) {
if (mPaint.getAlpha() != alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
#Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
invalidateSelf();
}
#Override
public void setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
invalidateSelf();
}
#Override
public void setDither(boolean dither) {
mPaint.setDither(dither);
invalidateSelf();
}
}
Any help on this pls?
You might try to do it with canvas clipPath():
// First we draw draw backgroudn, it should be cropped with path too
canvas.drawOval(mRectF, paintBackground);
// Creating path that will cover small area on the circle,
// it might be triangle or rectancel or what ever.
// Currently it is triangle between top and left rect centers.
path.reset();
path.moveTo(0, 0);
path.lineTo(0, mRectF.width() / 2f);
path.lineTo(mRectF.height() / 2f, 0);
path.close();
// Clipping canvas to path and drawing small area
canvas.save();
canvas.clipPath(path);
canvas.drawOval(mRectF, paintArc);
canvas.restore();

How to make border more smooth

I want to add border for view, border width, color, radius can be set by user. So I try to draw a rect for it. When I use drawRoundRect to draw, the line at the corner is not smooth, it is thicker than the other places too. I don't know how to fix it. Please give me some instruction. Is there any other way to do it? I have to use code to draw it.
Thanks very much.
attached code: red corner of rect.
past code:
public class MPCTextView extends TextView {
// private Context context;
private final static String TAG = "MPCTextView";
public final static int DEFAULT_BACKGROUND_COLOR = Color
.parseColor("#28FF28");
public final static int DEFAULT_BORDER_COLOR = Color.parseColor("#FF0000");
public int mBoderWidth = 2;
public int mBoderColor;
public int mBoderRadius = 20;
public int mbackgroundColor;
public boolean isHaveBorder = true;
public boolean isHaveBackground = true;
RectF mRectF = new RectF();
Rect mRec = new Rect();
Paint mPaint = new Paint();
public MPCTextView(Context context) {
super(context);
// this.context = context;
}
#Override
protected void onDraw(Canvas canvas) {
// try to add a boder for this view.
canvas.getClipBounds(mRec);
// draw background
// canvas.drawColor(mbackgroundColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(DEFAULT_BACKGROUND_COLOR);
if (mBoderRadius > 0) {
mRectF.set(mRec);
canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);
} else {
canvas.drawRect(mRec, mPaint);
}
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mBoderWidth);
mPaint.setColor(DEFAULT_BORDER_COLOR);
mPaint.setAntiAlias(true);
if (mBoderRadius > 0) {
mRectF.set(mRec);
canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);
} else {
canvas.drawRect(mRec, mPaint);
}
super.onDraw(canvas);
}
The core of the problem is the padding, not AntiAliasing. The corner is not thicker, rather, it is the normal width. But, the straight line is clipped.
If you set the stroke width to 2, the really straight line width is 1 because the stroke is rectangular and the axis is the line x = 0. This means the rectangle is (left=0,up=-1,right=length,bottom=1), but the up -1 is outside of the canvas, so it will not be painted. And the corner is full width, because it is in the canvas.
So, you just to need set the padding.
Here is the code to make the rounded rect draw completely inside the canvas:
float pad = 1f;
mRectF.set(new RectF(mRec.left + pad, mRec.top + pad, mRec.right - pad, mRec.bottom - pad));
canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);
Set the antialias to the paint you are using to draw the red rectangle . For instance
mPaint.setAntiAlias(true);
I want this code to be help you.
public int mBoderWidth = 2;
public int mBoderColor;
public int mBoderRadius = 20;
public int mbackgroundColor;
public boolean isHaveBorder = true;
public boolean isHaveBackground = true;
RectF mRectF = new RectF();
Rect mRec = new Rect();
Paint mPaint = new Paint();
public MPCTextView(Context context) {
super(context);
// this.context = context;
}
#Override
protected void onDraw(Canvas canvas) {
// try to add a boder for this view.
canvas.getClipBounds(mRec);
// draw background
// canvas.drawColor(mbackgroundColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(DEFAULT_BACKGROUND_COLOR);
if (mBoderRadius > 0) {
mRectF.set(mRec);
canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);
} else {
canvas.drawRect(mRec, mPaint);
}
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mBoderWidth);
mPaint.setColor(DEFAULT_BORDER_COLOR);
mPaint.setAntiAlias(true);
if (mBoderRadius > 0) {
mRectF.set(mRec);
///////////// look at this code
mRectF.left += mBorderWidth/2;
mRectF.right -= mBorderWidth/2;
mRectF.top += mBorderWidth/2;
mRectF.bottom -= mBorderWidth/2;
canvas.drawRoundRect(mRectF, mBoderRadius, mBoderRadius, mPaint);
mRectF.left -= mBorderWidth/2;
mRectF.right += mBorderWidth/2;
mRectF.top -= mBorderWidth/2;
mRectF.bottom += mBorderWidth/2;
} else {
canvas.drawRect(mRec, mPaint);
}
super.onDraw(canvas);
}
I know I am answering this question very late but it may help others modify your code like below will work
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

Create Custom control with Event click

I am creating a custom control as below in the image. It is a semicircle with places 1, 2 etc.
When user click on one place (1, 2 etc), it changes color (for example user click on place 3, image 2).
I try to use canvas and methods draws. But I don't think that is correct. Can you help me with a better solution and how to set up an event for user clicking on the place?
You can do it with the canvas, bellow is a small example of a View with 2 oval shapes that change color(to red) on a touch event:
class ExtraView extends View {
private boolean flag1, flag2;
private Paint p1, p2;
private RectF oval1, oval2;
public ExtraView(Context context) {
super(context);
flag1 = false;
flag2 = false;
// bigger oval paint
oval1 = new RectF(50, 50, 460, 360);
p1 = new Paint();
p1.setStrokeWidth(2.0f);
// smaller oval paint
oval2 = new RectF(140, 140, 360, 260);
p2 = new Paint();
p2.setStrokeWidth(2.0f);
}
#Override
public void draw(Canvas canvas) {
canvas.drawColor(Color.GREEN);
// bigger oval
if (flag1) {
p1.setColor(Color.RED);
} else {
p1.setColor(Color.WHITE);
}
p1.setStyle(Paint.Style.FILL);
canvas.drawOval(oval1, p1);
p1.setColor(Color.BLACK);
p1.setStyle(Paint.Style.STROKE);
canvas.drawOval(oval1, p1);
// smaller oval
if (flag2) {
p2.setColor(Color.RED);
} else {
p2.setColor(Color.WHITE);
}
p2.setStyle(Paint.Style.FILL);
canvas.drawOval(oval2, p2);
p2.setColor(Color.BLACK);
p2.setStyle(Paint.Style.STROKE);
canvas.drawOval(oval2, p2);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (oval2.contains(event.getX(), event.getY())) {
flag2 = !flag2;
invalidate();
} else if (oval1.contains(event.getX(), event.getY())) {
flag1 = !flag1;
invalidate();
}
}
return true;
}
}

Categories

Resources