Custom shape for RelativeLayout Android - android

Is it possible to create custom shape like image below on relativelayout ?
i've tried with this code :
#Override
protected void onDraw(Canvas canvas) {
int w = this.getWidth() - (this.getWidth()/4);
int w2 = this.getWidth() - (this.getWidth()/6);
int h = this.getHeight();
Point a = new Point(0, 0);
Point b = new Point(w, 0);
Point c = new Point(w2, h);
Point d = new Point(0, h);
Path path = new Path();
path.moveTo(a.x, a.y);
path.lineTo(b.x, b.y);
path.lineTo(c.x, c.y);
path.lineTo(d.x, d.y);
path.lineTo(a.x, a.y);
path.close();
Paint p = new Paint();
p.setColor(Color.WHITE);
canvas.drawPath(path, p);
super.onDraw(canvas);
}
But it is not working. Any idea ?

Related

Drawing a text using static layout, draws the text outside of the specific rectangle in android using canvas

I want to draw a text in a rectangle of specific size, but the result i m getting is not satisfactory.
Here is the code i have tried till now:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCanvas = canvas;
parentRect = new Rect();
mCanvas.getClipBounds(parentRect);
maxLeft = parentRect.left;
maxTop = parentRect.top;
maxRight = parentRect.right;
maxBottom = parentRect.bottom;
// custom drawing code here
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
// make the entire canvas white
paint.setColor(Color.GRAY);
canvas.drawPaint(paint);
String txt = getContext().getString(R.string.txt_graphics_rotation);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
paint.setTextSize(50);
paint.setTextAlign(Paint.Align.CENTER);
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(scaleFactor, scaleFactor);
rect = new Rect();
paint.getTextBounds(txt, 0, txt.length(), rect);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
Log.e(TAG, "onDraw: rect : " + rect.left + " : " + rect.top + " : " + rect.right + " : " + rect.bottom);
Paint paint1 = new Paint();
paint1.setColor(Color.BLUE);
paint1.setStrokeWidth(5);
paint1.setStyle(Paint.Style.STROKE);
canvas.save();
TextPaint textPaint = new TextPaint();
textPaint.set(paint);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
StaticLayout staticLayout = StaticLayout.Builder
.obtain(txt, 0, txt.length(), textPaint, parentRect.width())
.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setIncludePad(true)
.build();
if (staticLayout.getLineCount() == 1) {
widthOfText = textPaint.measureText(txt);
heightOfText = -textPaint.ascent() + textPaint.descent();
} else {
widthOfText = staticLayout.getWidth();
heightOfText = (staticLayout.getHeight());
}
canvas.translate(widthOfText / 2, heightOfText / 2);
staticLayout.draw(canvas);
canvas.drawRect(0, 0, widthOfText, heightOfText, paint1);
canvas.restore();
} else {
canvas.drawText(txt, rect.left, rect.top / 2, paint);
widthOfText = paint.measureText(txt) / 2;
heightOfText = rect.height();
canvas.restore();
}
}
Here i am getting the rectangle and text in different position, but i want to merge them.
Note : i know i have not followed the best practice, please ignore it for now.

Add a drawable within a specified "Path" variable in android?

I am drawing a hexagonal path in android app. Now I want to place an image in the drawn path. Below is the code I am using to draw the path.
combPath = getHexPath(cellWidth / 2f, cellWidth / 2f, (float) (cellWidth * Math.sqrt(3) / 4));
fillPaint.setColor(cellSet[c][r] ? Color.RED : Color.WHITE);
canvas.drawPath(combPath, fillPaint);
Method getHexPath()
private Path getHexPath(float size, float centerX, float centerY) {
Path path = new Path();
for (int j = 0; j <= 6; j++) {
double angle = j * Math.PI / 3;
float x = (float) (centerX + size * Math.cos(angle));
float y = (float) (centerY + size * Math.sin(angle));
if (j == 0) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
}
return path;
}
Now I have to place an image in the hexagonal path using "path()" variable. How can I achieve it?
TIA
Try to use something like this:
Bitmap bitmap = getBitmap(); // retrieve bitmap that you want to draw somehow
Paint paint = new Paint();
paint.setAntiAlias(true);
combPath = getHexPath(cellWidth / 2f, cellWidth / 2f, (float) (cellWidth * Math.sqrt(3) / 4));
canvas.drawPath(combPath, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, 0, 0, paint);
UPDATED
Here is an example function of how you can do that
private Bitmap getCroppedBitmap(Bitmap original) {
Bitmap output = Bitmap.createBitmap(original.getWidth(),
original.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, original.getWidth(), original.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
Path path = new Path();
path.moveTo(30, 20);
path.lineTo(120, 30);
path.lineTo(110, 120);
path.lineTo(20, 110);
path.lineTo(30, 20);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(original, rect, rect, paint);
return output;
}
You just need to place your bitmap, play with width/height and also insert your path. This code worked for me.

Draw and fill custom shape

I'm trying to create a custom shape using the Path object in Android and I'm running into a weird problem.
What I'm trying to achieve is depicted in the picture below
Here is the code I'm using to draw and fill the shape:
public class BallView extends RelativeLayout {
....
protected void onDraw(Canvas canvas) {
...
PaintArc(canvas);
}
private void PaintArc(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setAntiAlias(true);
p.setStyle(Paint.Style.FILL_AND_STROKE);
p.setStrokeWidth(2);
p.setColor(Color.RED);
RectF oval = new RectF(20, 20, getWidth() - 20, getHeight() - 20);
RectF oval2 = new RectF(0, 0, getWidth(), getHeight());
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.addArc(oval, 0, 180);
path.addArc(oval2, 0, 180);
float y=20+oval.height()/2;
float x=20;
path.moveTo(x,y);
path.lineTo(x - 20, y);
x=oval.width()+20;
path.moveTo(x,y);
path.lineTo(x+20,y);
path.close();
canvas.drawPath(path, p);
}
}
The actual result that I'm getting looks like this:
The resulting shape without Filling looks like this:
Can you tell me what I'm doing wrong ?
try this:
class MyView extends View {
private Path mPath;
private Paint mPaint;
private RectF mOval;
public MyView(Context context) {
super(context);
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(0xffff0000);
mOval = new RectF();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
int dx = w / 4;
mOval.set(0, 0, w, w);
mPath.reset();
mPath.moveTo(0, w / 2f);
mPath.arcTo(mOval, 180, 180);
mPath.rLineTo(-dx, 0);
mOval.inset(dx, dx);
mPath.addArc(mOval, 0, -180);
mPath.rLineTo(-dx, 0);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xffffffff);
mPaint.setStyle(Style.FILL);
canvas.drawPath(mPath, mPaint);
canvas.translate(0, getWidth() / 2);
mPaint.setStyle(Style.STROKE);
canvas.drawPath(mPath, mPaint);
}
}
- I have just edited my answer
and i add below code
RectF oval3 = new RectF(10, 20, getWidth() - 10, getHeight() - 10);
/**
*Now check this code output seem like your thought
*/
private void PaintArc(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setAntiAlias(true);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(2);
p.setColor(Color.RED);
Paint p1 = new Paint(Paint.ANTI_ALIAS_FLAG);
p1.setAntiAlias(true);
p1.setStyle(Paint.Style.STROKE);
p1.setStrokeWidth(10);
p1.setColor(Color.RED);
RectF oval = new RectF(20, 20, getWidth() - 20, getHeight() - 20);
RectF oval2 = new RectF(0, 0, getWidth(), getHeight());
RectF oval3 = new RectF(10, 20, getWidth() - 10, getHeight() - 10);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.addArc(oval, 0, 180);
path.addArc(oval2, 0, 180);
path.addArc(oval3, 0, 180);
float y = 20 + oval.height() / 2;
float x = 20;
path.moveTo(x, y);
path.lineTo(x - 20, y);
x = oval.width() + 20;
path.moveTo(x, y);
path.lineTo(x + 20, y);
path.close();
canvas.drawArc(oval3, 0, 180, false, p1);
canvas.drawPath(path, p);
}

Drawing 2 circles on a canvas

I'm trying to draw two circles like this:
This is how I'm trying to do it:
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Canvas c = new Canvas(bmp);
RectF rect = new RectF(0,0,width,width);
Paint paint = new Paint();
drawCircles(paint, c, width, height, width);
ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setImageBitmap(bmp);
img.setScaleType(ScaleType.FIT_CENTER);
And here is my drawCircles() method:
private void drawCircles(Paint paint, Canvas c, int width, int height, int radius) {
paint.setARGB(255, 255 , 10, 21);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStyle(Paint.Style.STROKE);
if(width < height && radius == 0){
radius = width/2;
height = width;
} else if (radius == 0){
radius = height/2;
width = height;
}
Paint paint2 = new Paint();
paint2.setARGB(255, 255 , 10, 21);
paint2.setStrokeWidth(10);
paint2.setAntiAlias(true);
paint2.setStrokeCap(Paint.Cap.BUTT);
paint2.setStyle(Paint.Style.STROKE);
c.drawCircle(width/2, height/2, radius-10, paint);
c.drawCircle(width/2, height/2, 50, paint2);
}
I don't know why but I get only one circle, the small one (the one drawn with paint2).
What can be the reason?
Try this code.Hope it may helps :)
public class SimpleCircleActivity extends Activity
{
private CircleDemoView circledemoView ;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
circledemoView =new CircleDemoView(this);
setContentView(circledemoView);
}
private class CircleDemoView extends View
{
public CircleDemoView(Context context)
{
super(context);
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint p = new Paint();
p.setColor(Color.RED);
DashPathEffect dashPath = new DashPathEffect(new float[]{5,5}, (float)1.0);
p.setPathEffect(dashPath);
p.setStyle(Style.STROKE);
for (int i = 0; i < 2; i ++) {
canvas.drawCircle(200, 200, 50+(i*40), p);
}
invalidate();
}
}
}

Drawing static text in a rotating canvas

So i have this onDraw function
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
int w = canvas.getWidth();
int h = canvas.getHeight();
int cx = w / 2;
int cy = h / 2;
canvas.translate(cx, cy);
if (mValues != null) {
canvas.rotate(-mValues[0]);
}
canvas.drawPath(mPath, mPaint);
Paint paint1 = new Paint();
paint1.setColor(Color.BLACK);
paint1.setTextSize(25);
canvas.drawText("Some Text", 10, 25, paint1);
}
And what it does it draws a arrow that is rotating and the text is also rotating near the arrow what I want is a static text somewhere under the arrow... or something like that.
Use canvas.save(); and canvas.restore(); something like:
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
int w = canvas.getWidth();
int h = canvas.getHeight();
int cx = w / 2;
int cy = h / 2;
canvas.save();
canvas.translate(cx, cy);
if (mValues != null) {
canvas.rotate(-mValues[0]);
}
canvas.drawPath(mPath, mPaint);
canvans.restore();
Paint paint1 = new Paint();
paint1.setColor(Color.BLACK);
paint1.setTextSize(25);
canvas.drawText("Some Text", 10, 25, paint1);
}
Hope that helps.

Categories

Resources