Is there any way in Android to draw a filled rectangle with say a black border. My problem is that the canvas.draw() takes one paint object, and to my knowledge the paint object can't have a different color for the fill and the stroke. Is there a way around this?
Try paint.setStyle(Paint.Style.FILL) and paint.setStyle(Paint.Style.STROKE).
Paint paint = new Paint();
Rect r = new Rect(10, 10, 200, 100);
#Override
public void onDraw(Canvas canvas) {
// fill
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.MAGENTA);
canvas.drawRect(r, paint);
// border
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
canvas.drawRect(r, paint);
}
If you are drawing multiple views then you could also use two paints, one for the stroke and one for the fill. That way you don't have to keep resetting them.
Paint fillPaint = new Paint();
Paint strokePaint = new Paint();
RectF r = new RectF(30, 30, 1000, 500);
void initPaints() {
// fill
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setColor(Color.YELLOW);
// stroke
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setColor(Color.BLACK);
strokePaint.setStrokeWidth(10);
}
#Override
protected void onDraw(Canvas canvas) {
// First rectangle
canvas.drawRect(r, fillPaint); // fill
canvas.drawRect(r, strokePaint); // stroke
canvas.translate(0, 600);
// Second rectangle
int cornerRadius = 50;
canvas.drawRoundRect(r, cornerRadius, cornerRadius, fillPaint); // fill
canvas.drawRoundRect(r, cornerRadius, cornerRadius, strokePaint); // stroke
}
You draw a rectangle with the color of the border and the size of the rectangle plus the border, you change the color of the paint and draw again the rectangle with the normal size.
Related
I want to draw an oval shape inside another oval shape, but the second one should be cut off when it reaches the border of the first one.
This is the desired result:
How can this be achieved?
I want to draw an oval shape inside another oval shape, but the second one should be cut off when it reaches the border of the first one.
As pskink said, you could use PorterDuffXfermode to implement this feature, here is an simple :
public class DrawView : View
{
public DrawView(Context context):base(context)
{
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint();
paint.SetARGB(255, 255, 0, 0);
RectF oval2 = new RectF(60, 100, 300, 200);
canvas.DrawOval(oval2, paint);
//PorterDuff.Mode.SrcAtop means Discards the source pixels that do not cover destination pixels. Draws remaining source pixels over destination pixels
paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.SrcAtop));
paint.Color = Color.Black;
RectF oval3 = new RectF(110, 150, 350, 250);
canvas.DrawOval(oval3, paint);
this.SetLayerType(LayerType.Software, null);
paint.SetXfermode(null);
}
}
Effect :
On a canvas I draw figures covering each-other to get the result I want. Their transparent is 128 and on cover areas color multiple. I need whole figure in one color. How to fix it?
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
Path path = new Path();
path.moveTo(margin,0);
path.lineTo(middleWidth+pieceWidth,0);
path.lineTo(middleWidth-pieceWidth,height);
path.lineTo(margin, height);
path.lineTo(margin, 0);
Path path1 = new Path();
path1.moveTo(middleWidth+pieceWidth+interval,0);
path1.lineTo(middleWidth-pieceWidth+interval,height);
path1.lineTo(width-margin,height);
path1.lineTo(width-margin,0);
path1.lineTo(middleWidth+pieceWidth+interval,0);
RectF rect = new RectF();
rect.set(0,0,middleWidth-pieceWidth,height);
RectF rect1 = new RectF();
rect1.set(middleWidth+pieceWidth,0,width,height);
paint.setStyle(Paint.Style.FILL);
paint.setColor(leftColor);
paint.setAlpha(128);
canvas.drawPath(path, paint);
paint.setColor(rightColor);
paint.setAlpha(128);
canvas.drawPath(path1, paint);
paint.setAlpha(128);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(rect, corners, corners, paint);
canvas.drawRoundRect(rect1, corners, corners, paint);
}
The result is:
Result picture
Hello i added rectangle in my canvas now i want to add textview or some other view in that rectangle.Suggest me some tutorial also. Thanks in advance
public class DrawView extends View {
public DrawView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect();
rect.set(20 ,10 ,canvas.getWidth()/2, canvas.getHeight()/2);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
canvas.drawRect(rect, paint);
}
}
You can draw text on your canvas.
Paint mpaint= new Paint();
mpaint.setColor(Color.RED);//set red color for rectangle
mpaint.setStyle(Paint.Style.FILL);//mpaint will fill the rectangle
Paint paint2 = new Paint();
paint2.setColor(Color.GREEN);//green color for text
paint2.setTextSize(30f);//set text size. you can change the stroke width also
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawRect(30, 30, 600, 600, mpaint);
canvas.drawText("hello", 150, 150, paint2);//change x and y according to your needs
}
Resulting snapshot on samsung galaxy s3
Adding a View of any kind is out of question here since you are simply drawing on a canvas. But Canvas.drawText(...) might be exactly what you are looking for.
I'm overriding Android's ImageView in order to make the corners of my image transparent. I can accomplish that clipping the canvas in my onDraw(Canvas canvas):
#Override
protected void onDraw(Canvas canvas) {
Path clipPath = new Path();
int w = this.getWidth();
int h = this.getHeight();
clipPath.addRoundRect(new RectF(0,0,w,h), 10.0f, 10.0f, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
Unfortunately, it's not possible to antialias this round rectangle, and the result are ugly corners like this:
I know I can clear parts of my canvas with antialiasing using Paint and PorterDuff.Mode.CLEAR, what I don't know is to specify the round corners as the region to be erased. I'm looking for something like this:
#Override
protected void onDraw(Canvas canvas) {
//superclass will draw the bitmap accordingly
super.onDraw(canvas);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
//this will erase a round rectangle, I need the exact inverse
canvas.drawRoundRect(rect, rx, ry, paint);
}
Is there any way to "erase" not the round rectangle, but it's inverse, ie, the round corners? And what if I just want to erase one of the corners?
Draw using a BitmapShader with a transparent color for your Paint object.
If you just want to erase one of the corners, try drawing it as a Path instead of a RoundRect.
protected void onDraw(Canvas canvas) {
BitmapShader bitmapShader = new BitmapShader(<original drawable>, TileMode.CLAMP, TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(0xFF000000);
paint.setShader(bitmapShader);
canvas.drawRoundRect(rect, rx, ry, paint);
}
I want to draw an oval shape around the text on Canvas, I am displaying the 3 texts on Canvas using drawwText() method.
Now when I click on a particular text, I need to draw an oval around that text and again when we click on another text, the oval shape should appear on the clicked text. For this give me some code suggestions.Thanks in advance
use drawOval method().. here is the signature of the method..
public void drawOval (RectF oval, Paint paint)
RectF is class for drawing rectangle...whose constructor is defined as following...
RectF(x,y,x+width,y+height);
you can make its object as follows
RectF rect = new RectF(x,y,x+width,y+height);...
now pass this object in drawOval method....
canvas.drawOval(rect,paint);
for resolution (480 x 800)
in onCreate()
setContentView(new SampleView(this));
create class
private static class SampleView extends View {
// CONSTRUCTOR
public SampleView(Context context) {
super(context);
setFocusable(true);
}
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
//1
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
RectF oval1 = new RectF(0, 0, 250,250);
Paint p1 = new Paint();
p1.setColor(Color.BLACK);
canvas.drawText("Parent", 30, 50, p1);
canvas.drawOval(oval1, paint);
//2
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLUE);
RectF oval2 = new RectF(50, 50, 150, 150);
Paint p2 = new Paint();
p2.setColor(Color.GREEN);
canvas.drawText("Child", 75, 75, p2);
canvas.drawOval(oval2, paint);
}
}