Android: Drawing Text on Canvas overlaps - android

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.

Related

Draw shapes dynamic

I am developing an application for technical drawing and I need to add a few tools to draw lines, circles, rectangles and corners. Now I can draw lines and free hand drawing but I cannot draw circles, rectangles and corners. I found in lot of websites how to draw it but static, I mean, draw the shape in the position you pre-set or the position where you touch but I need to know how to draw, for example, a circle in the position I touch and make it bigger than I separate my fingers. I hope you understand what I mean.
You can have two variables x and y, then every time you touch the screen set x and y to that value, while drawing draw the circle with coordinates x and y.
If you are drawing and you just want to keep a painted circle, you can paint the circle and add it inside your canvas on x and y, then the next time you touch the screen a new circle will be painted on x and y and the old one will remain painted.
Are you using Canvas ? if so you can find out how to do this here (Canvas documentation) and here (Bitmap documentation). Depending on your situation you can create a new Bitmap and assign it to Canvas then draw on the Canvasand inside your bitmap you will have your desired circles and other shapes, on the next drawing frame, draw new shapes and the changes will remain.
Edit: In order to have dynamic radius follow this logic, when you touch the screen, set x and y to that point (the center of the circle), while moving the finger on the screen, calculate the radius comparing to x and y, when lifting your finger apply the drawing on the bitmap as told above.
Some code:
public boolean onTouchEvent(MotionEvent e)
{
switch (e.getAction())
{
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
//If I'm not wrong this is how to calculate radius,
//I'm at work and can't test this now, you can use your way
int distanceX = (int) event.getX() -x;
int distanceY = (int) event.getY() -y;
radius = sqrt(distanceX *distanceX + distanceY *distanceY);
break;
case MotionEvent.ACTION_UP:
//Draw circle inside your bitmap here
//This is like a flag to notify the program that no new shape is being drawn
x = -1;
break;
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(myBitmap, 0, 0, null);
//A new shape is being drawn
if (x != -1)
//In here you place a switch to decide which shape you are drawing
//for this example i assume circle
canvas.drawCircle(radius, x, y, paint);
}
When you are lifting your finger the new circle should be painted on your bitmap so you don't have to add extra code for each new circle.
Edit2: I will add more code with the Bitmap and Canvas method i described.
Bitmap myBitmap;
Canvas myCanvas;
//Constructor
public myActivity(Bundle bundle) //or whatever your constructor is
{
myBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
myCanvas = new Canvas(myBitmap);
}
Now anything you draw on "myCanvas" will be applied to "myBitmap", when ACTION_UP activates draw circle on "myCanvas" which is drawn on the draw function.
case MotionEvent.ACTION_UP:
myCanvas.drawCircle(radius, x, y, paint);
x = -1;
break;

How to draw multiple texts on canvas

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.

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.

How to determine whether or not user touch the oval in canvas?

I draw a oval in canvas by following codes and that works fine:
Paint paint = new Paint();
canvas.drawOval(new RectF(10, 10, 300, 100), paint);
When user click on screen, how could I determine whether or not user click within the oval?
Notes:
When I draw a Rect, I can use Rect.contains(int x, int y) to determine whether user click within it. But now I am drawing a oval.
Thanks in advance!
When you touch the screen you'll get the x and y coordinates. You also can know the center or you oval.
x, y are coordiantes when touched, center_x and center_y are coordinates of the center of the oval. R is the radius.
float dx = Math.abs(x-center_x);
float dy = Math.abs(y-center_y);
float R = radius ;//radius of circle.
boolean checkDistance(float dx,float dy,float R)
{
if(dx>R)
{
return false;//outside
}
else if(dy>R)
{
return false;//
}
else
{
return true;
}
}
Actually this solution is for a circle but you can get a good approximation using it or maybe could open your mind to change this code for your purpose.

Android canvas drawText y-position of text

I'm using a Canvas to create a Drawable with some background and some text. The drawable is used as a compound drawable inside an EditText.
The text is drawn via drawText() on the canvas, but I do have an issue with the y-position of the drawn text in some cases. In those cases parts of some characters are cut off (see image links).
Characters without positioning issue:
http://i50.tinypic.com/zkpu1l.jpg
Characters with positioning issue, text contains 'g', 'j', 'q', etc.:
http://i45.tinypic.com/vrqxja.jpg
You can find a code snippet to reproduce the issue below.
Does any expert know how to determine the proper offset for the y position?
public void writeTestBitmap(String text, String fileName) {
// font size
float fontSize = new EditText(this.getContext()).getTextSize();
fontSize+=fontSize*0.2f;
// paint to write text with
Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.DKGRAY);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.SERIF);
paint.setTextSize((int)fontSize);
// min. rect of text
Rect textBounds = new Rect();
paint.getTextBounds(text, 0, text.length(), textBounds);
// create bitmap for text
Bitmap bm = Bitmap.createBitmap(textBounds.width(), textBounds.height(), Bitmap.Config.ARGB_8888);
// canvas
Canvas canvas = new Canvas(bm);
canvas.drawARGB(255, 0, 255, 0);// for visualization
// y = ?
canvas.drawText(text, 0, textBounds.height(), paint);
try {
FileOutputStream out = new FileOutputStream(fileName);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
}
}
I think it's probably a mistake to assume that textBounds.bottom = 0. For those descending characters, the bottom parts of those characters are probably below 0 (which means textBounds.bottom > 0). You probably want something like:
canvas.drawText(text, 0, textBounds.top, paint); //instead of textBounds.height()
If your textBounds is from +5 to -5, and you draw text at y=height (10), then you'll only see the top half of the text.
I believe that if you want to draw text near the upper left corner you should do this:
canvas.drawText(text, -textBounds.left, -textBounds.top, paint);
And you can move around the text by summing the desired amount of displacement to the two coordinates:
canvas.drawText(text, -textBounds.left + yourX, -textBounds.top + yourY, paint);
The reason why this works (at least for me) is that getTextBounds() tells you where drawText() would draw the text in the event that x=0 and y=0. So you have to counteract this behavior by subtracting the displacement (textBounds.left and textBounds.top) introduced by the way text is handled in Android.
In this answer I elaborate a little more on this topic.

Categories

Resources