I am trying to create a hollow circle and then put image inside it. I have imageview statically in my XML file. But the hollow circle I am creating is dynamically with the use of Paint class.
The issue is I can draw both and are visible but when I put hollow circle over image it overlaps imageview and image is not visible.
Another issue is I do not know how to put both of them in center of layout.
Here is my java code snippet
RelativeLayout rl = (RelativeLayout) findViewById(R.id.panel);
Circle view = new Circle(MyActivity.this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
rl.addView(view);
Code to draw circle
private class Circle extends View {
public Circle(Context context) {
super(context);
}
#Override
public void draw(Canvas canvas) {
Paint mPaint = new Paint();
mPaint.setColor(Color.BLACK);
canvas.drawCircle((int) (500), (int) (430),
320, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawCircle((int) (500), (int) (430),
300, mPaint);
}
}
Can anybody help to define both image inside this circle in Center I know it need to pass x, y coordinates while drawing circle here but how to know center(x,y) - radius coordinate for circle. Thanks
Related
I have an image view that loads a drawable image. The imageview is set to wrap_content but since the original image is big then it fills the root layout.
I have pixels values of the Rect on the ORGINAL image that surrounds a face.
When I load this image to an imageview, I want to draw a rect around the face in the same fashion. So basically I want to convert the bitmap pixels to imageview pixels.
After researching, I am using this code:
// Where the rct is on original bitmap/image
Rect rct= new Rect(200,500,300,700);
//get Bitmap
Bitmap bmp = ((BitmapDrawable)ivPicture.getDrawable()).getBitmap();
//Calculate the scaling ratio
double bmpWidthRatio = bmp.getWidth()/(double)ivPicture.getWidth();
double bmpHeightRatio = bmp.getHeight()/(double)ivPicture.getHeight();
//create new image view so I can draw the rect in the canvas
ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.MATCH_PARENT);
MyView v = new MyView(this);
v.setLayoutParams(lp);
v.rect.set((int)(rct.left/bmpWidthRatio),(int)( rct.top/bmpHeightRatio) ,
(int)(rct.right/bmpWidthRatio),(int)( rct.bottom/bmpHeightRatio));
And here is code for the custom imageview to use to draw on Rect
public class MyView extends View {
public Rect rect = new Rect(0,0,0,0);
public MyView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint bracketsPaint = new Paint();
bracketsPaint.setColor(Color.YELLOW);
bracketsPaint.setStyle(Paint.Style.STROKE);
bracketsPaint.setStrokeWidth(10);
canvas.drawRect(rect, bracketsPaint);
}
}
What I don't understand with this code? I mean it looks like the box is drawn at the right X value but somehow the Y value is messed up.
Isn't this how you would convert original bitmap pixel to imageview pixel for the same spot?
Thanks
I'm trying to implement a custom drawable which should have the shape of a speechbubble. Therefore I use two paths, one draws the rect and the other should draw the triangle for the bubble.
My class looks like the following:
public class SpeechBubbleView extends Drawable {
private Paint mBubblePaint;
private Paint mBubblePaint2;
private Path mRectPath;
private Path mBubblePath;
public SpeechBubbleView() { }
public void initPaint() {
mBubblePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBubblePaint.setStyle(Paint.Style.FILL);
mBubblePaint.setColor(Color.GREEN);
mBubblePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
mBubblePaint2.setStyle(Paint.Style.FILL);
mBubblePaint2.setColor(Color.RED);
int width = getBounds().width();
int height = getBounds().height();
mRectPath = new Path();
mRectPath.addRoundRect(new RectF(0, 0, width, height), 8, 8, Path.Direction.CW);
mRectPath.close();
mBubblePath = new Path();
mBubblePath.moveTo(50, height);
mBubblePath.lineTo(100, height + 50);
mBubblePath.lineTo(150, height);
mBubblePath.close();
}
#Override
public void draw(Canvas canvas) {
if(mRectPath == null && mPathValues == null) {
initPaint();
}
canvas.drawPath(mRectPath, mBubblePaint);
canvas.drawPath(mBubblePath, mBubblePaint2);
}
#Override
public void onBoundsChange(Rect bounds) {
Rect customBound = new Rect(0, 0, bounds.width(), bounds.height() + 50);
super.onBoundsChange(customBound);
}
The problem now is, that I take the width and height from the drawable to draw the rect of the speechbubble. The full space of the canvas is taken and there is no more room for the triangle to display below the rect.
My question now is: Is it possible to change the size of canvas or the drawable, so that I am able to display the small triangle below the rect?
I already tried the method onBoundsChange, but it takes no effect. In the draw-method the size is still the same.
If possible, it would be nice to change the size directly in the custom drawable class, shown above, because I do not have the size of the view, when I call it. Also I cannot make the size of the rect smaller, because in the drawable there is content and if the rect is smaller, some of the content will be outside of the drawable. I use a drawable, so that I can simple call setBackgroundDrawable of my layout or TextView and it matches always the content size.
If anyone of you got an idea on how to do the size change, this would be very great. Thank you :D
I have developed a custom rounded LinearLayout and I want to add 1px border.
Here my code :
public class MyLinearLayout extends LinearLayout {
private float radius;
private Path path = new Path();
private RectF rect = new RectF();
public MyLinearLayout(Context context)
{
super(context);
radius = 20;
setWillNotDraw(false);
}
#Override
protected void onDraw(Canvas canvas) {
path.reset();
rect.set(0, 0, canvas.getWidth(), canvas.getHeight());
path.addRoundRect(rect, radius, radius, Direction.CCW);
// Add 1px border RED here ?
path.close();
canvas.clipPath(path);
}
}
Thanks for your help.
If you look closely at the rounded corners in your custom LinearLayout, you will probably see that the radius is not smooth. This is because there is a system limitation that does not support anti aliasing on Paths.
Here is a great tutorial from Erik Burke on how to properly create Views with rounded corners. Basically you will create an off-screen Bitmap, draw a RoundRectangle, and use an alpha compositing technique to merge the off-screen Bitmap with the custom LinearLayout Canvas' Bitmap.
As far as a border, you can can draw it by setting Paint.Style.FILL_AND_STROKE to the Paint.
I'm just getting into basic drawing with Android. I'm starting off with a few simple shapes but I'm having a few issues. I'd like to draw a circle at the center of a canvas. I looked at a few examples but can't seem to make it work. I think it's because I don't really understand what variables go where.
Could someone please explain the proper way to draw my circle at the center of my screen. Here is my code:
public class Circle extends View{
int width = this.getWidth();
int height = this.getHeight();
public Circle(Context context) {
super(context);
setFocusable(true);
}
protected void onDraw(Canvas canvas){
canvas.drawColor(Color.CYAN);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
//canvas.drawCircle(100, 100, 50, paint);
canvas.drawCircle(width/2, height/2, 100, paint);
Display disp = ((WindowManager)this.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
float radius = 0;//Radius caused an error so I initialized this variable
canvas.drawCircle(disp.getWidth()/2, disp.getHeight()/2, radius, paint);
}
}
width and height of the view have not been yet initialized when getWidth() and getHeight() are called, just use getWidth() and getHeight() in onDraw:
canvas.drawCircle(getWidth()/2, getHeight()/2, 100, paint);
You can also override onSizeChanged and get view width and height.
PS: do not create anything in onDraw, create the paint object in the constructor.
public void drawCircle(Graphics2D g, int x, int y, int radius) {
x = x-(radius/2);
y = y-(radius/2);
g.fillOval(x,y,radius,radius);
}
here x,y is the position of canvas where you want to draw circle and you can find it with motion listener if you want to set x,y position dynamically hope this will help you
There are some links which are very useful for us and I hope they will work for you and other.
https://github.com/swapgo20/Android-Hand-Drawing
https://github.com/codepath/android_guides/wiki/Basic-Painting-with-Views
https://github.com/Korilakkuma/CanvasView
I hope above links are very useful to draw shapes on canvas.
I suggest you use third link and use only Path class (http://developer.android.com/reference/android/graphics/Path.html) of android to draw shapes.
I have a SurfaceView where I'm setting a background color and an image like so:
BitmapDrawable tiledBackground = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.background));
tiledBackground.setTileModeX(Shader.TileMode.REPEAT);
tiledBackground.setColorFilter(0xaacceeff, PorterDuff.Mode.DST_OVER);
this.setBackgroundDrawable(tiledBackground);
I also have an animation thread where I'm drawing an image (successively adjusting its x coordinate so that it appears to move to the left). The background image is a transparent PNG and so some parts of it are transparent. It appears that the image I'm drawing from the thread appears below the background drawable on the SurfaceView. How can I have it appear on top of the background? I'm drawing the image like so:
private void doDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(missile, x, getHeight() - 95, paint);
canvas.restore();
}
missile and paint are initialized in the constructor of the thread to:
missile = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.missile));
paint = new Paint();
Each call to doDraw should draw everything you want to be displayed, including the background.
// Add to initializer
tiledBackground = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.background));
tiledBackground.setTileModeX(Shader.TileMode.REPEAT);
tiledBackground.setColorFilter(0xaacceeff, PorterDuff.Mode.DST_OVER);
private void doDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
// Create a rectangle (just holds top/bottom/left/right info)
Rect drawRect = new Rect();
// Populate the rectangle that we just created with the drawing area of the canvas.
canvas.getClipBounds(drawRect);
// Make the height of the background drawing area equal to the height of the background bitmap
drawRect.bottom = drawRect.top + tiledBackground.getBitmap().getHeight();
// Set the drawing area for the background.
tiledBackground.setBounds(drawRect);
tiledBackground.draw(canvas);
canvas.drawBitmap(missile, x, getHeight() - 95, paint);
canvas.restore();
}