Set Text at center of layout that contains Canvas - android

I have a situation like below
In my linear layout i added one View (MyView) that contains canvas
drawLayout.addView(new MyView(this,"a"));
Now i want to draw one text in canvas at middle of the linearlayout, for that i calculate linearlayout's height and width (drawWidth,drawHeight) and then wrote this,
canvas.drawText(letterTOdraw,drawWidth/2,drawHeight/2,mpaint);
But it was not draw correctly (not in center). After that i modify it as below
canvas.drawText(letterTOdraw,canvas.getWidth()/2,canvas.getHeight()/2,mpaint);
But nothing changed. When i calculate canvas height and width, i am surprised that i gave me 600 X 1024 , how it is possible that i set MyView into linearLayout that is only 951X359.
Thus i can't able to draw text at center of linearLayout.
I am stuck in this problem for last 5 hrs . help me to get out of this.

Your centering code is wrong. Your code will draw the text not in the center, but rather slightly to the bottom and to the right - the center of the canvas will be the top-left point of the text.
If you want to draw the text in the center, you need to take into account the size of the text - at ((canvas.getWidth() - letterWidth) /2, (canvas.getHeight() - letterHeight) / 2))

Related

Android - Canvas not drawing after Translation?

I am working on a custom view where i draw lines horizontally one after another left to right. When the collective width of all the lines combined crosses the width of the view , i translate the view. After translating the view , the view moves leftward , but canvas.drawLine stops drawing lines as soon as i translate the view. Any solution to this problem?
for(someCondition){
canvas?.drawLine(startX,startY,stopX,stopY,linePaint)
if(startX > (width)){
log("Invisible , setting translation to ${-(startX - width)}")
translationX = -(startX - width)
}
log("width is $width and startX is $startX")
}
as soon as i translate , the canvas stops drawing but translate keeps happening.
I solved the problem without having to translate anything.
Everytime the collective width of the lines crossed the width of the View , i increased the starting index of the array so that i drew only n elements, where n is the max number of lines that can fit inside the views width. This solution also helped avoid drawing unnecessary lines everytime a new element was added to the array.

Relation between canvas coordinates and screen coordinates android

What is the relation between screen's X and Y and canvas's X and Y. Suppose canvas's height is half of screen's height and it's center aligned. Now, i want to draw something with respect to screen's coordinates. What should I do? Please help
When you draw in your canva in your onDraw method it is relative to your view. You can't draw beyond your view. For exemple if your view is at the position x = 0, y = 0, width = 50, height = 50. If you try to draw a line in your view like that canva.drawline(25,0,100,0) it's just gonna draw a line from 25x to 50x in your view, it's not gonna go beyond the limit of the View.
Tell me if you need clarification ;).
Edit:
So taking your exemple:
If your view is at the position 200dp, 100dp, 50w, 50h. Let's say you want to draw a line from the 0x,0y axes of your screen to the edge 0x,0y axes of your view. For this you have to do a custom that will match_parent in width and height. Then you will have to have the x, y of your view (view.getX(), view.getY()). The in the onDraw you'll just have to do that:
canvas.drawLine(0,0, myview.getX(), myview.getY(), paint);
You can have something like that:

Android canvas Drawable position translation

I Created my custom view in which i placed one drawable, I need to change its position. I have 2 Rectangles(Rect) which have the top, bottom left, right. Now I need to give translation effect by Changing Rect.
Lets suppose Rect1 have top = 100 & Rect2 have top = 200. So I need to do translation from 100 to 200 with anim duration.
Any help is appreciated.

Open PopupWindow and drawing from RightTop to LeftBottom, instead of LeftTop to RightBottom

I know I can use:
myPopup.showAtLocation(layout, Gravity.NO_GRAVITY, x, y);
// OR
myPopup.showAtLocation(layout, Gravity.TOP|Gravity.LEFT, x, y);
To open a PopupWindow that's drawn from [x, y] as the Top-Left of the PopupWindow, drawn towards to Bottom-Right.
What I want instead however, is to draw from [x, y] as the Top-Right of the PopupWindow, drawn towards the Bottom-Left.
Here is a picture to make it more clear (The dot is my [x, y] position and the rectangle is my PopupWindow. The first picture shows how it's normally done, and the second is what I want to achieve.):
So how do I correctly calculate the x and y of the second picture's gray point's location, while knowing the black point's location? I know the y can stay the same, but the x should be changed to something like:
x minus PopupWindow-width
The problem is that the PopupWindow's width and height are both set to wrap_content, so I don't know the size until after I draw it.
Does this mean I have to draw it (but make it invisible at first), then calculate the new x with the PopupWindow's MeasuredWidth in it's ViewTreeObserver's OnGlobalLayoutListener (to know when it's done rendering and the MeasuredWidth is known), then apply this new x and then make it Visible? Or is there an easier way to just let it draw at the correct position?
PS: I've also changed Gravity.NO_GRAVITY to Gravity.TOP|Gravity.RIGHT, if the PopupWindow is out of the screen it will automatically place it at the border of the Right/Top side (whichever side it's out of the screen).
You could get the size of your popup window by overriding the onMeasure method of the popup window (note that you have to subclass a View in order to do this). After that, you can calculate the offset of the x and y coordinates. Hope this helps.

What is programmatically equivalent to android:layout_centerInParent="true" of RelativeLayout?

I place an ImageView of a pin in the center of the layout by using android:layout_centerInParent="true" in my RelativaLayout XML file.
Now I wish to draw the green dot at the same position as the pin on the canvas.
NOTE: the green dot is NOT a view. It is drawn on canvas by canvas.drawCircle();
That is, I have to programmatically get the coordinates of the pin.
So how can I get the coordinates of android:layout_centerInParent="true" with codes?
My guess is
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, 1);
You can get layoutParams by relativeLayout.getLayoutParams(), and don't forget to setLayoutParams back when you're done modifying it.
To get the width and height of the parent you can do this.
RelativeLayout parent = (RelativeLayout) findViewById(R.id.yourRelativeLayout);
int width = parent.getWidth();
int height = parent.getHeight();
Then you can divide these numbers by 2 and set that to as your green dot's coordinates and it should appear in the middle of your screen. For this to work your canvas size has to be the same as the relative layout.
But beware, you need to call getWidth() and getHeight() methods after the activity has been created, else you will end up getting zero. See this answer
So, the canvas you are drawing to is in a view that is contained by the RelativeLayout, but you want to draw the dot at the center of the RelativeLayout?
Yes, that is exactly what I am trying to do!
Assuming the canvas view is a direct child of the RealtiveLayout, this should work.
You can get the layout's center by using getWidth() / 2 and getHeight() / 2 on the layout as others mentioned. However, you also have to figure out where the origin of the canvas is. For this you can just use getLeft() and getTop() on the canvas view. Then you just subtract the center x from left, and center y from top to get your final spot.
Example:
Assume each grid line is 1. The RelativeLayout is the large black rectangle, and the Canvas view is the blue one. The center dot's coordinates are 4,6. Using left/top, you get 1,4 for the canvas origin(red dot). Subtract, and you get 3,2, which are the local canvas coordinates for the green dot.
Drawing the dot in the center of the canvas should just be a matter of dividing the width and height of the view by two. If you want it to be at the base of the pin (as opposed to the true center), then just add half the height of the pin to the circle's y value.

Categories

Resources