Android canvas Drawable position translation - android

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.

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.

How to draw circle with alpha gradient on canvas?

How to draw on canvas like this pic with alpha gradient?
Please specify next time whether you mean the android app canvas or HTML5 canvas on android browsers. If its the former, use android-canvas. This solution is in JS since its easier to show, and will work fine on either platform.
Gradients along paths in canvas are hard. The easiest way is to fudge it.
Instead of thinking of your image as a gradient that follows a circular path, think of it as two linear gradients.
One on the left side, going from green to gray, top to bottom.
The other on the right side, going from white to gray, top to bottom.
Imagine a square made of those two gradients:
Now imagine a circle cutting through:
That's all you gotta do.
To "cut" through like that its easiest to use clipping regions, so I've made an example doing that.
Here's the live example: http://jsfiddle.net/simonsarris/Msdkv/
Code below:
var greenPart = ctx.createLinearGradient(0,0,0,100);
greenPart.addColorStop(0, 'palegreen');
greenPart.addColorStop(1, 'lightgray');
var whitePart = ctx.createLinearGradient(0,0,0,100);
whitePart.addColorStop(0, 'white');
whitePart.addColorStop(1, 'lightgray');
var width = 20;
ctx.lineWidth = width;
// First we make a clipping region for the left half
ctx.save();
ctx.beginPath();
ctx.rect(-width, -width, 50+width, 100 + width*2);
ctx.clip();
// Then we draw the left half
ctx.strokeStyle = greenPart;
ctx.beginPath();
ctx.arc(50,50,50,0,Math.PI*2, false);
ctx.stroke();
ctx.restore(); // restore clipping region to default
// Then we make a clipping region for the right half
ctx.save();
ctx.beginPath();
ctx.rect(50, -width, 50+width, 100 + width*2);
ctx.clip();
// Then we draw the right half
ctx.strokeStyle = whitePart;
ctx.beginPath();
ctx.arc(50,50,50,0,Math.PI*2, false);
ctx.stroke();
ctx.restore(); // restore clipping region to default

want to create a semi doughnut shape button clickable in a particular region

I want to create a semi doughnut shaped button which is only clickable in the region where it is visible and not in the the whole rectangular region.
http://i.stack.imgur.com/MKD45.png
I want clicking to affect only this blue region.
You can do this by grabbing the Bitmap representation of the Button, then testing the x/y pixel's alpha value.
To get the bitmap for a button:
Bitmap buttonBmp;
button.setDrawingCacheEnabled(true);
buttonBmp = Bitmap.createBitmap(button.getDrawingCache());
button.setDrawingCacheEnabled(false);
I'd recommend only doing this once, and saving the results, that way you're not creating a new bitmap every time you touch the button.
Then you override the Button's onTouchEvent so you have the local x/y where the user tapped. If the alpha in that spot is 0, you have a non-clickable area. It's not as simple as an onClickListener, but it should do the job.
This way you can use any arbitrary shape, not just a doughnut. Colors, textures, whatever.
I'm not entirely sure on this but I think this scheme would work. Create an image view in your layout to display the picture and make it clickable via an onTouchEvent. This way you can get the coordinates of the click. Check to make sure that the click is within the inner and outer radii and if it is, do the given response.
Here are a few calculations that will need:
Center of circle
-Assuming the center is the very bottom of the image, this will look something like this(not necessarily exact methods)
centerX = img.getX() + img.getWidth()/2;
centerY = img.getY() + img.getHeight()/2;
Remember that screen coordinates go from top to bottom and from left to right.
Find the distance away from the center where the click occurred
Dx = click.getX() - centerX;
Dy = click.getY() - centerY;
D = Math.sqrt(Dx^2 + Dy^2);
Then all you need is to check if the distance is within the radii(not sure how to get the exact radii here, may just need to guess and check. An alternative may be that the top of the semicircle is the top of the picture and then the max height with be the outer radius.)
if(D<=outerR && D>=innerR)
respond();

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.

Set Text at center of layout that contains Canvas

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))

Categories

Resources