create a slanted rectangle drawable in android xml - android

I would like to create rectangle drawable then rotate it so top right side appear slanted, i would eventually overlay over rounded corner image ,in effort to create a copy of the image below , using some drawable
am hoping for using with xml , but it just slanted and edge never touch other side
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item >
<rotate
android:fromDegrees="19.5"
android:toDegrees="-19.5"
android:pivotX="-50%"
android:pivotY="0%"
>
<shape
android:shape="rectangle" >
<solid
android:color="#android:color/black" />
</shape>
</rotate>
</item>
create a custom Drawable that draws the shape: but again i fail , would love any help ? thank you
#Override
public void draw(Canvas canvas) {
int width = this.getBounds().width();
int height = this.getBounds().height();
double angle = 19.5 * (Math.PI / 180.0);
double offsetX = height * Math.tan(angle);
Path path = new Path();
Paint paint = new Paint();
path.moveTo(0, 0);
path.lineTo(width, 0);
path.lineTo(width, height);
path.lineTo((int)offsetX, height);
path.close();
paint.setColor(_color);
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, paint);
}

Related

Scale drawable circle according to screen size

Its been a while I am stuck with this. I am a newbie android developer.
I have a drawable circle.
circular_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:useLevel="false"
android:shape="ring"
android:thickness="0.8dp">
<solid android:color="#android:color/holo_blue_dark"/>
</shape>
now i want to use this circle in my activity layout in such a way that it covers the whole screen. That is, the width of the screen should be equal to Diameter of the circle.
Note that I have not set the radius of the circle.
example_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/exampleLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.anil.raceorganizer.ExampleActivity">
<ImageView
android:id="#+id/race_field"
android:src="#drawable/circular_shape"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:padding="0dp"
android:layout_margin="0dp"
></ImageView>
</FrameLayout>
Note that I have tried to put padding and margin as 0, but it didn't work.
I also tried setting the size of the ImageView through code, but it only changed the size of the ImageView as a whole and not circle alone.
This is what I get with this code.
Any help is greatly appreciated.
You can try this code:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:thickness="0.8dp"
android:useLevel="false"
android:innerRadiusRatio="2.1">
<solid android:color="#android:color/holo_blue_dark" />
</shape>
Using Canvas, we can draw shapes matching the screen width.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Canvas c = new Canvas(bmp);
RectF rect = new RectF(0,0,width,width);
drawCircle(rect, c, width, height);
}
private void drawCircle(RectF rect, Canvas c, int width, int height) {
Paint paint = new Paint();
paint.setARGB(255, 255 , 10, 21);
paint.setStrokeWidth(8);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStyle(Paint.Style.STROKE);
int radius;
if(width < height)
radius = width/2;
else
radius = height/2;
radius-= 4;
c.drawCircle(width/2, height/2, radius, paint);
}
Not sure if it might help you. If its not , let me know. I will prefer deleting than getting downvotes!
Try this
You can use this tag in drawable
android:innerRadius="150dp"
change the radius accordingly
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
use the width from the above
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:useLevel="false"
android:shape="ring"
android:innerRadius="150dp"
android:thickness="0.8dp">
<solid android:color="#android:color/holo_blue_dark"/>
</shape>
Use this kind of approach to get ring like structure.
Use size tag to preserve 1:1 aspect ratio
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<size android:width="50dp"
android:height="50dp"/>
<stroke android:color="#000" android:width="0.1dp"/>
</shape>

Android drawable oval shape with center out of bound

I'm willing to declare a xml drawable with semi-circle. So the center of the oval is out of the bound:
I tried doing it with scale tag but i can't get it to work, here is what i have done.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<scale android:scaleGravity="center">
<shape android:shape="ring">
<stroke
android:width="2dp"
android:color="#C8C8D7"/>
<size
android:width="300dp"
android:height="300dp"/>
</shape>
</scale>
</item>
</layer-list>
But it doesn't work.
I didn't manage to generate it inside xml. I ended up using canvas drawing.
public Drawable generateHeaderBackground(int arcColor) {
int w = screenWidth;
x = (int) r.getDimension(R.dimen.header_height);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(w, x, conf);
Canvas mCanvas = new Canvas(bmp);
Paint p = new Paint();
p.setStyle(Paint.Style.STROKE);
p.setColor(arcColor);
p.setStrokeWidth(3);
p.setAntiAlias(true);
RectF rtt = new RectF(-w / 2, x / 4, w + (w / 2), x * 8);
mCanvas.drawOval(rtt, p);
return new BitmapDrawable(getResources(), bmp);
}

how to draw a half circle in android

I'm using this code to draw a half in my app:
<?xml version="1.0" encoding="utf-8" ?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:left="35dp"
android:top="40dp"
android:bottom="40dp"
android:right="0dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" android:innerRadius="30dp" android:thickness="0dp">
<solid android:color="#color/transparent"/>
<stroke android:width="3dp" android:color="#color/White"/>
</shape>
</item>
</layer-list>
output :
but i need something like below :
how to draw this ?
I would suggest to draw it through code.
1- Create class MyView and put below code.
public class MyView extends View {
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
float width = (float) getWidth();
float height = (float) getHeight();
float radius;
if (width > height) {
radius = height / 4;
} else {
radius = width / 4;
}
Path path = new Path();
path.addCircle(width / 2,
height / 2, radius,
Path.Direction.CW);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL);
float center_x, center_y;
final RectF oval = new RectF();
paint.setStyle(Paint.Style.STROKE);
center_x = width / 2;
center_y = height / 2;
oval.set(center_x - radius,
center_y - radius,
center_x + radius,
center_y + radius);
canvas.drawArc(oval, 90, 180, false, paint);
}
}
2-Initialize this class inside you activity or fragment:-
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
Your can use a rectangle shape .xml file and edit the corners on one side only.
Example:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="30dp"
android:width="30dp"/>
<solid android:color="#color/black"/>
<corners android:topLeftRadius="15dp"
android:bottomLeftRadius="15dp"/>
</shape>
You can use <clip /> drawable in order to cut-off part of your circle.
http://developer.android.com/guide/topics/resources/drawable-resource.html#Clip
this is how i created my semi circle in a drawable xml file.
<size
android:width="180dp"
android:height="90dp"></size>
<corners
android:topLeftRadius="200dp"
android:topRightRadius="200dp"></corners>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="180dp"
android:height="90dp"></size>
<corners
android:topLeftRadius="200dp"
android:topRightRadius="200dp"></corners>
<stroke android:width="5px" android:color="#color/black" />
</shape>

Scaling then rotating a rectangle drawable

I would like to scale a rectangle drawable downwards, then rotate it so once it is clipped by the view it resembles a trapezoid with the left side slanted:
The rotation is working fine:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item >
<rotate
android:fromDegrees="-19.5"
android:toDegrees="-19.5"
android:pivotX="0%"
android:pivotY="0%"
>
<shape
android:shape="rectangle" >
<solid
android:color="#android:color/black" />
</shape>
</rotate>
</item>
</layer-list>
However to prevent a big gap where the rectangle has rotated away from the bottom of the view I want to scale vertically by 200% before the rotation happens. I was hoping that I could do something like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item >
<scale
android:scaleWidth="100%"
android:scaleHeight="200%"
android:scaleGravity="top"
>
<rotate
android:fromDegrees="-19.5"
android:toDegrees="-19.5"
android:pivotX="0%"
android:pivotY="0%"
>
<shape
android:shape="rectangle" >
<solid
android:color="#android:color/black" />
</shape>
</rotate>
</scale>
</item>
</layer-list>
but this just causes the rectangle to disappear. Does anyone know how best to achieve this?
No really a true answer but I solution that I am using now is to create a custom Drawable that draws the shape:
public void setColor(int color) {
_color = color;
}
#Override
public void draw(Canvas canvas) {
int width = this.getBounds().width();
int height = this.getBounds().height();
double angle = 19.5 * (Math.PI / 180.0);
double offsetX = height * Math.tan(angle);
Path path = new Path();
Paint paint = new Paint();
path.moveTo(0, 0);
path.lineTo(width, 0);
path.lineTo(width, height);
path.lineTo((int)offsetX, height);
path.close();
paint.setColor(_color);
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, paint);
}
This does the job for now, although it is frustrating that I cannot find a way to do this in the xml.

Android layout background xml texture

I searched a lot but didn't find anything. I want to make a background for a layout , but instead of filling it with a color or a gradient I want to fill it with a texture and repeat it . I tried this but it didn't work . Can you tell me a solution.
card_texture.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/paper_texture"
android:tileMode="repeat"
/>
card_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color = "#android:color/transparent"/>
<stroke android:width="2dp"
android:color="#color/text_color"/>
<corners
android:radius="20dp"
/>
</shape>
card_background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/card_texture" >
<corners
android:radius = "20dp"/>
</item>
<item android:drawable="#drawable/card_shape" />
</layer-list>
and this is how I use it in my Layout android:background="#drawable/card_background"
I get something like this. But I want the corners(marked with red) of the texture to be transparent and to fit in the black border
I called this res/drawable/bg_tile.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/tile"
android:tileMode="mirror"
android:dither="true"
android:antialias="true"
/>
I use it like:
android:background="#drawable/bg_tile"
Obiously, I prepared a tile to be mirrored horizontally and vertically (most tiles make a funny effect like that) and called it res/drawable-a-dpi-resolution/tile.png
a-dpi-resolution being ldpi, mdpi, ..., xxxhdpi
If you want to use a composite background (i.e. a gradient and a tiling bitmap over it - but the bitmap has to be somehow transparent, or it will cover the gradient), you can make a LayerList background (so that different "layers" are dran one ontop of another)
To do that, you'll need to add another background file, i.e.: res/drawable/bg_radial.xml:
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<gradient
android:startColor="##color/bar_int_md"
android:centerColor="##color/bar_mid_md"
android:endColor="##color/bar_ext_md"
android:gradientRadius="480"
android:type="radial"
/>
</shape>
and finally the LayerList, which sticks them together (res/drawable/bg.xml):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/bg_radial" />
<item android:drawable="#drawable/bg_tile" />
</layer-list>
Note that the first item is drawn first. Next items are drawn ontop of each other, being the last one the "uppermost".
So, finally you would use this like:
android:background="#drawable/bg"
Nice!
to make your image corners rounded use following function:
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
in onCreate do this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu)
View rl = (View) findViewById(R.id.root);//get the reference of the layout that you set as background
LayerDrawable layer = (LayerDrawable) rl.getBackground();
BitmapDrawable bg = (BitmapDrawable) layer.getDrawable(1);
Drawable d =new BitmapDrawable(getRoundedCornerBitmap(bg.getBitmap(),10));//pass corner radius
layer.setDrawableByLayerId(1, d);
rl.setBackgroundDrawable(d);
}

Categories

Resources