How to draw multiple texts on canvas - android

I've created a drawing app and now I'm trying to allow the user to add text to the drawing. The text will be placed anywhere on the screen where the user touches with his finger. With the following code, the text could be drawn on screen with the drawing. However, this is only done once. The moment I tap on the screen, the previous text disappears and the new text is placed at my current finger position.
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(canvasColor);
for(Pair<Path, Paint> p : paths){
canvas.drawPath(p.first, p.second);
}
canvas.drawPath(drawPath, drawPaint);
if(textCB && !pbCol)
{
tPaint = new Paint();
tPaint.setTextSize(textSize);
tPaint.setStyle(Paint.Style.FILL);
tPaint.setColor(tColor);
canvas.drawText(addText, tx, ty, tPaint);
}
}
What can I do to allow multiple text to be drawn on the canvas?

Ok, I found a way to do this. After drawing the text, I got the bitmap from getDrawingCache, then drew the bitmap onto the canvas.

Related

Android Google Map cleared by PorterDuff.Mode.CLEAR

I'm trying to draw a rectangle above the google map to crop a portion of the map.
I placed a googleMap and a custom layout with a canvas like this.
<FrameLayout>
<FrameLayout/>//conatiner for SupportMapFragment
<MyCustomLayout/>
</FrameLayout>
Inside MyCustomLayout, the paints are initiated like this.
linedPaint.setStyle(Paint.Style.STROKE);
linedPaint.setStrokeWidth(5f);
linedPaint.setColor(getResources().getColor(R.color.colorBlack));
linedPaint.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
bgPaint = new Paint();
bgPaint.setColor(0x70FFFFFF);
transparentPaint = new Paint();
transparentPaint.setStyle(Paint.Style.FILL);
transparentPaint.setColor(getResources().getColor(android.R.color.transparent));
transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
onDraw is as below.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
try {
canvas.drawRect(0, 0, getWidth(), getHeight(), bgPaint);
canvas.drawRect(mClickStartX, mClickStartY, mClickEndX, mClickEndY, transparentPaint);
canvas.drawRect(mClickStartX, mClickStartY, mClickEndX, mClickEndY, linedPaint);
} catch (Exception e) {
ErrorController.showError(e);
}
}
This will draw a dim white background above the map, and when the user clicks and drags on it, it will draw a transparent rectangle.
But, when the transparentPaint's xfermode is set to PorterDuff.Mode.CLEAR, it clears the map itself, resulting as a black rectangle shown as below.
When changing the xfermode to OVERLAY, it doesn't change the map to black, but the background of the canvas will not be changed as I expect.
When switching to a Naver Map fragment, it works as I expect it to be. What can I try to make this work? Please help!

Android: Drawing Text on Canvas overlaps

I am trying to draw several Text objects onto my canvas however my text got overlapped on the canvas.
My codes are as follows:
for (RectF rec : rects) {
for(String name : nameArr){
if (rec.height() != 50 ) {
canvas.drawOval(rec, paintColor);
canvas.drawText(name, x, y, paint);
} else {
canvas.drawRect(rec, paintColor);
canvas.drawText(name,x,y, paint);
}
for (String text : name) {
canvas.drawText(text, x, y, fontpaint);
}
The X and Y are from my touch coordinates every time when I touch the canvas, the text object should be drawn on the canvas. Also how can i move those text objects around the canvas? by redrawing them? Please advice thank you.
image of my output: http://postimg.org/image/3y39kt0cb/
rect 1 shld remain at the first rect on the left but it overlapped with the second one.

Connect the dots of an imageview

It is a difficult task to create an app for kids and i am given a task of creating an connect the dots app.
example
https://play.google.com/store/apps/details?id=zok.android.dots
i have done some tutorials of onTouchEvent.
i know how to paint on screen Draw in Canvas by finger, Android
i am getting the dot coordinates using this Android: How do I get the x y coordinates within an image / ImageView? example
but I really don't know how to achieve this target.
I'd really appreciate a solution to this! Thanks!
input image is http://imgur.com/Z24yQUx,t6nL71r
EDIT
#Override
protected void onDraw(Canvas canvas) {
//backgroundBitmap is the image i want to show in background
if(DISPLAY_ALPHABET==0)
{
canvas.drawBitmap(backgroundBitmap, 0f, 0f, null);
DISPLAY_ALPHABET=1;
}
show(canvas);
}
public void show(Canvas canvas)
{
Paint paint = new Paint();
int cnt=1;
canvas.drawPaint(paint);
//color of numbers
paint.setColor(Color.BLUE);
paint.setTextSize(16);
canvas.drawColor(BACKGROUND);
** canvas.drawBitmap(mBitmap, 0, 0, null);**
canvas.drawPath(mPath, mPaint);
mPaint.setColor(Color.BLACK);
//Drawing points on canvas
for (Point point : mPoints) {
canvas.drawPoint(point.x, point.y, mPaint);
canvas.drawText(""+cnt++, point.x-7, point.y-7, paint);
}
mPaint.setColor(Color.RED);
}
I don't have much idea about this but still felt like worth thinking
You can save the next dot coordinates in a arraylist or a vector.
when you are drawing the line using canvas, check whether the Motion-Event x and y coordinates matches to that of the next point in the vector.
Once a coordinate is touched search for the next one in the vector
You can use a counter to increase the vector position, once the dot touched increment the counter.
EDIT: Check out my Demo App in this Link and check what you might need.

Smooth bitmap movement in canvas (android)

I tried to create a Maze with a moving ball and a hole using the Accelerometer Sensor. With the following code, the ball falls into the hole, but the performance is really bad, I set the Accelerometer Frequency to the fastest, but it's everything other than smooth. I made a second canvas, because so I could make a hole.
public RenderView(Context context, int width, int height) {
super(context);
playGround = new Rect(40, 40, width - 40, height - 40);
holes.addElement(new PointF(500f, 500f));
// Set background
this.setBackgroundResource(R.drawable.bottom);
// Set bitmap
woodGround= wood.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(woodGround);
// Set eraser paint properties
eraserPaint.setAlpha(0);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
eraserPaint.setAntiAlias(true);
}
protected void onDraw(Canvas canvas) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG
| Paint.FILTER_BITMAP_FLAG);
paint.setStyle(Style.FILL_AND_STROKE);
paint.setAntiAlias(true);
if (ballInHole)
canvas.drawBitmap(ball, b.x, b.y, paint);
bitmapCanvas.drawBitmap(wall, 0, 0, paint);
bitmapCanvas.drawBitmap(wood, playGround, playGround, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
for (PointF h : holes) {
bitmapCanvas.drawCircle(h.x + radius, h.y + radius, radius,
eraserPaint);
}
if (!ballInHole)
canvas.drawBitmap(ball, b.x, b.y, paint);
invalidate();
}
It's solved very ugly, because I just draw the ball bellow the other bitmaps when he falls into a hole. Is there another way to do it?
The performance is also really bad, i set the Accelerometer-Sensor-Delay to the fastest, but the ball doesn't run smooth. When I remove the line canvas.drawBitmap(bitmap, 0, 0, paint);, then the ball is smoother, but then the wooden background is away.
The problem here is that you're doing A LOT of drawings all the time and that's take time to draw and the performance gets very low.
here a few tips on how you should approach it.
You probably better have one view with the static stuff (the background image and the holes) and on your layout have a second view on top of it just drawing the ball.
on the background image, do not call invalidate. That way you will draw the background just once.
and the top image (the ball only) you can invalidate, so it can redraw on the new position.
I'm not sure on this last part: but you may need to call invalidate(rect); passing the area where the ball was on the previous time, to make the background only re-draw that small area (instead of the whole screen)
happy coding.

Canvas Larger Than Screen

I am drawing a grid and I want it to be larger than the screen size so that a user can drag the screen left/right/up/down to get to the rest of the grid.
What is the best way to do that? I've tried drawing a larger bitmap to the canvas, but didn't get anywhere.
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
Bitmap testBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
canvas.drawBitmap(testBitmap, 0, 0, paint);
canvas.drawPaint(paint);
//other grid drawing code here
}
I used the View's scrollBy() method in the onTouch method of the Activity. It worked.
You can probably use the canvas.translate(x, y) method. That will adjust the origin for your canvas in relation to the screen. So canvas.translate(10, 10) will make you canvas origin (0, 0) be at the point of (10, 10) on the screen. Use a negative translation to scroll the screen.

Categories

Resources