android create drawable that is intersection between circle and rectangle - android

I would like to create an android xml drawable. That is the intersection between a circle and a rectangle.
Basically, i would like to have a rectangle. And then on the corner of this rectangle, draw a circle.
I would like to have the intersection of these two shapes to be used for a background.
This circle should have a radius slightly less than the height of the rectangle. So the intersection is not just 1/4 of the circle.
Is this something that can be created in a XML drawable in android?
Here is a very poorly drawn image using a trackpad..
The rectangle is what I would like to have for my background image. The shaded area should be able to have some color that I can change manually in the xml.

I would use a <vector> drawable here.
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="80dp"
android:viewportWidth="48"
android:viewportHeight="80">
<path
android:pathData="M48 0 a80 80 0 1 0 0.1 0z"
android:fillColor="#caf"/>
</vector>
You can then apply this to your layout using the android:background attribute:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/circle_rect_intersection"
...>
You can even tint it (to get different colors) using android:backgroundTint on your root view.

Related

Android XML Drawable: Rounded Rectangle With Inner Edge Gradient

I'm currently drawing a simple rounded rectangle using an XML drawable (black BG for contrast):
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#android:color/white"/>
<corners android:radius="15dp" />
</shape>
What I would like to achieve is adding an inside outline/glow that is a gradient so that it looks like this:
I know it will most likely involve several XML gradient elements in a layer list, but where I get stuck creating this is figuring out how to:
Have the gradient follow the curves in the corners since they are rounded (always face towards the center of the rectangle, or as close as possible)
Avoid the effect having double intensity in the corners like it is in the example. This will happen if 4 gradients are simply overlapped or a radial gradient stretched to a ellipse is used. The density of the outer color needs to be consistent all the way around the rectangle, or as close as possible
It is highly preferable if feasible that the implementation is modifiable so that:
I can control how far into the rectangle the gradient reaches
I can control how quickly the gradient fades at any given distance (control its density/intensity)
I can remove any side from the gradient so that I can have only 1 or 2 edges and their corners glow if needed
This is a perfect example of what I need except that it is obviously much simpler to do with a circle and a radial gradient. I need this consistent pattern but with the rounded rectangle:

How to make semi circle (arc) view in layout

I want to make an arc view in my layout , I've tried to use a library but it doesn't works fine , how can I make an arch view like this and attache a button to it for example :
I've tried some codes but they wasn't displaying properly on tablet and different size of screens
Here's a custom solution I've came up with.
It's basically using
view with height of x dp as main box
another view with oval shape as background
adjusting the oval shape below the rectangular view above, about half it's height
For various screens you have to define the height/margin values in values.xml files though, but works fine I guess.
inside of which can be seen like this
Here's the layout file for this.
Not an elegent solution, but someone might benefit from this I think.
If you are developing for API >= 21, then vector path may be a solution.
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="500.0"
android:viewportHeight="500.0"
android:width="50dp"
android:height="50dp">
<path
android:fillColor="#color/colorAccent"
android:pathData="M0 0 H500 V300 H-500"/>
<path
android:fillColor="#color/colorAccent"
android:pathData="M0,300 L500 300, A4,2 0 1,1 0,210 Z"/>
</vector>
What we are doing here is draw two vector paths (maybe possible with one path only, but for demonstration purposes I am going to explain with two paths).
The first path
<path
android:fillColor="#color/colorAccent"
android:pathData="M0 0 H500 V300 H-500 Z"/>
In the first line we setup the color for the shape. Then in the second line actual working starts.
M0 0, this moves the cursor to (x,y) = (0,0)
H500, this draws a horizontal line from (0,0) to (500,0)
V300, this draws a vertical line from (500,0) to (500,300)
H-500, this draws a line from (500,300) to (0, 300)
Z, this closes the path, i.e. joins the first (0,0) and last (500,300) points together.
So, we end up drawing a nice rectangle shape (try to comment the second path's code to see that rectangle).
More explanation to come (for path 2)...

android:pivotY doesnt add top-padding to my android vector drawable

I have compactTextView with compoundDrawable.
I want to add top padding to that compoundDrawable which is fed by vector image (I imported svg into android studio)
I saw this post on how to add padding to a vector drawable
but when i try this, no padding is added:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="13dp"
android:height="8dp"
android:autoMirrored="true"
android:viewportHeight="8.11"
android:viewportWidth="13.44">
<group
android:pivotX="0"
android:pivotY="12"
android:scaleX="1"
android:scaleY="1">
<path
android:fillColor="#FF000000"
android:pathData="M6.71,8.12l-6.71,-6.7l1.42,-1.42l5.29,5.3l5.29,-5.3l1.42,1.42z"/>
</group>
</vector>
do I need to add anything else?
The linked solution works by scaling down the path inside your VectorDrawable.
In the other example the viewPortWidth and viewportHeight were 24.
The pivotX and pivotY are the origin for the transform. It's equivalent to transform-origin in CSS. So thus setting the scaleX and scaleY to 0.5, results in their icon scaling down from 24x24 to 12x12, with the centre at the pivot point (12,12).
Thus you end up with a 12x12 icon in the middle of a 24x24 VectorDrawable. Thus creating a padding of 6 around the entire thing.
In your icon you have the scale attributes set to 1. So no scaling will happen, and you won't create any padding.
Are you sure you want to create padding space in your icon? The normal way to introduce padding is via your layout. For instance with android:layout_marginTop or android:paddingTop. I recommend you consider that approach first.
If you really do want to adjust your VectorDrawable. Then what you want to do to create padding only at the top, is to scale the shape down towards the bottom of the icon.
So have your pivot point at the bottom of the icon:
android:pivotX="0"
android:pivotY="8.11"
and scale down by an appropriate amount
android:scaleX="0.5"
android:scaleY="0.5"
Here we are scaling down toward the bottom left of the icon, so we are therefore also going to create padding on the right. Because we are also scaling in the X direction. You could counter that by reducing the width and viewportWidth.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="7dp"
android:height="8dp"
android:autoMirrored="true"
android:viewportWidth="6.72"
android:viewportHeight="8.11">
<group
android:pivotX="0"
android:pivotY="8.11"
android:scaleX="0.5"
android:scaleY="0.5">
<path
android:fillColor="#FF000000"
android:pathData="M6.71,8.12l-6.71,-6.7l1.42,-1.42l5.29,5.3l5.29,-5.3l1.42,1.42z"/>
</group>
</vector>
You could also prevent the extra padding on the right by leaving scaleX at "1", but that will result in your icon having the appearance of being squashed vertically.
The translation approach
Another approach would be just to move the icon vertically downwards, to create space at the top, instead of scaling it in size. This has the advantage that you can more explicitly set the padding you want.
You do that by using the translateY attibute. Obviously that means that the height of the VectorDrawable has to change also. So you have to handle that by adjusting the viewportHeight.
In the example below, I have added a vertical padding of 4, mening the viewport height of the icon goes from 8.11 to 12.11.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="13dp"
android:height="12dp"
android:autoMirrored="true"
android:viewportWidth="13.44"
android:viewportHeight="12.11">
<group
android:translateY="4">
<path
android:fillColor="#FF000000"
android:pathData="M6.71,8.12l-6.71,-6.7l1.42,-1.42l5.29,5.3l5.29,-5.3l1.42,1.42z"/>
</group>
</vector>
If you do this, you may also need to adjust the android:width and/or android:height.
You can choose to either:
increase the android:height as well to match the extra padding (ie to "12"), or
keep the height at 8, and adjust the width down to compensate (eg "9").

Align XML drawable background to bottom of view

I am trying to provide a simple solid-color underline to a TextView header. I want this to be reusable and to work with any view in the future, regardless of height. I am trying to favor a background drawable so I can simply apply it to view. I can draw a line without any problem:
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:shape="line"
>
<stroke
android:color="#8a9299"
android:width="1dp"
/>
</shape>
This line is, however, centered in the background of the view. I see a bunch of online tutorials that use layers to draw a background-colored rectangle and then "peek" another rectangle from behind, however I don't know what background color this header element type will be used on, and transparent rectangle backgrounds show the color rectangle below. Is there any way to stick to a line but give it a bottom gravity inside the view it is applied to?
This can be achieved using gradientDrawable. Here you go:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:startColor="#000000"
android:centerColor="#android:color/transparent"
android:centerX="0.1" />
</shape>
Increase/Decrease centerX to increase/decrease width of your underline. Change startColor to change the color of the underline.
Explanation:
angle is the angle of the gradient. 0 is left to right. 90 is bottom to top.
startColor is the start color of the gradient. Our angle is 90 so the gradient starts from bottom (and so it appears like an underline)
centerColor is the centerColor which is transparent.
centerX is the X position of the gradient as a fraction of the width. Keep it small (<0.1) for a good looking underline. Anything above 0.1 looks bad (nobody is stopping you though!).

Fill only x percent of the background of a view in android?

In android , i want to fill only a part of the background (for example 70% from right or left) of a view by a color like black programitically.
How can I do that?
You could use (shape, gradient) to achieve this effect.
Android set the background color can be defined in a xml res/drawable,
as follows:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:angle="0"
android:endColor="#000"
android:startColor="#FFF" />
</shape>
Shape is used to define the shape, gradient inside the definition of the shape of the gradient fill, startColor starting color, endColor end color, angle indicates the direction angle. When the angle = 0, the gradient from left to right.
Then set shape to view background.
android:background="#drawable/background"
Just create a BitmapDrawable 10px wide #1px high, fill it with Color.TRANSPARENT and then draw a line from 0,0 to x,0 using your desired colour. Use Canvas to achieve all that.
Then call yourcontrol.setBackgroundDrawable(bitmap) an you're done

Categories

Resources