How to make a double gradient with XML (iphone like) - android

How can I make this kind of drawable gradient with XML?
I can do a simple gradient from color A to color B but i don't know how to combine two gradients in the same drawable.

I finally found a solution with a layer-list which is good enough for me :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- First part is a gradient -->
<item android:left="0dp" android:right="0dp">
<shape android:shape="rectangle">
<gradient android:angle="-90" android:startColor="#9dcbf6"
android:endColor="#177ee6" />
</shape>
</item>
<!-- Second part is plain color. Slightly transparent -->
<item android:top="1sp" android:bottom="20sp" >
<shape android:shape="rectangle">
<solid android:color="#10ffffff"/>
</shape>
</item>
</layer-list>
The middle is set to 20 sp because the container has a 40sp height , but you can adjust to your will by editing : android:bottom="20sp"

You can have three colors in a gradient. A start color, end color and a center color.
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:usesLevel=["true" | "false"] />
Alternatively you can use a LayerList Drawable and just piece them together.

Related

How is a bottom line added with this layer-list drawable?

I want to have a bottom line in a view. The following drawable somehow adds a bottom border:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:shape="rectangle">
<!-- Set the border color of your layout here -->
<solid android:color="#color/red" />
</shape>
</item>
<!-- This is for border bottom but
you can change this according to your need -->
<item android:bottom="2dp" >
<shape
android:shape="rectangle">
<!-- Set the background color of your layout here -->
<solid android:color="#color/green" />
</shape>
</item>
</layer-list>
The result of this is:
Problem:
1) I don't understand how this works at all. It seems this is some trick using margins to get a red bottom border but I don't really get it.
2) I need to be able to add a bottom border but I don't want to set any specific background color for the whole view. Is that possible?
This is telling the system from where to start this item layout.
Since here we have bottom 2dp so this layout start 2dp from bottom.
Change bottom to end,start or other options for more understanding.
For 2) I need to be able to add a bottom border but I don't want to set any specific background color for the whole view. Is that possible?
replace your drawable with below code:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff" />
<!--Uncomment this if you wnat to set any background color to
your rectangle
<solid android:color="#ffffff" />-->
<stroke
android:width="1dp"
android:color="#color/red" />
</shape>
</item>

Custom drawable speech bubble

I need to create a speech bubble background for an icons container like the white one in this image:
Required Appearance
I decided to use a drawable xml rather than a 9 patch image, so I can control of the rounded corner radii in my code. So, with the help of this answer to a related question, I have created the following xml:
bg_icons_container.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="0dp"
android:top="27dp"> <!-- How to make this 50% of height? -->
<rotate
android:fromDegrees="-45"
android:toDegrees="0"
android:pivotX="0%"
android:pivotY="0%"> <!-- How to make the triangle more acute? -->
<shape
android:shape="rectangle" >
<solid
android:color="#color/white"/>
</shape>
</rotate>
</item>
<item
android:left="10dp">
<shape
android:shape="rectangle">
<solid
android:color="#color/white"/>
<corners
android:radius="#dimen/border_radius_small"/>
</shape>
</item>
</layer-list>
This results in:
Actual Apperance (enlarged)
My problem is that the triangular part of the drawable is too wide. How can I make it more acute? (My minSdkVersion is 16, so I cannot use android_width on the first item to try and stretch it.)
Also, I am having to hard code android:top of the first item to 27dp. Is it possible to make this 50%, so it will correctly adjust when the height of the drawable changes?

Linear Gradient CenterX

I am trying to make a transparent gradient background for a button, something like this:
(The start color is not grey but transparent)
But I am getting this:
(where white portion is too narrow)
This is my gradient.xml:
<!-- Here centerX does not work -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:centerX="30%"
android:startColor="#android:color/transparent"
android:endColor="#android:color/white"/>
</shape>
I have also tried adding a centerColor, but then the transparent area turns to grey!
<!-- Here the startColor turns greyish -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:centerColor="#android:color/white"
android:centerX="30%"
android:endColor="#android:color/white"
android:startColor="#android:color/transparent" />
</shape>
Thanks in advance!
If what you need is just gradient moved to the left side of the drawable, try something like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="100dp">
<color android:color="#android:color/white"/>
</item>
<item android:width="100dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:centerX="30%"
android:endColor="#android:color/white"
android:startColor="#android:color/transparent"/>
</shape>
</item>
</layer-list>
This layer consist of two rectangles:
White rectangle moved to the right by 30dp
Gradient rectangle, whose width is 30dp
centerX works only when you have a centerColor set.
But if you set the center color to #android:color/transparent the gradient goes from opaque white to transparent black, not white.
#android:color/transparent is defined as #00000000, which is a transparent black and not white. Usually it doesn't matter because color is transparent anyway, but in case of gradients it gives a black tint.
So, you need
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#00ffffff"
android:centerColor="#00ffffff"
android:endColor="#ffffffff"
android:centerX="30%" />
</shape>
In this case the color is same (#ffffff i.e. white) across the gradient, but alpha is varied from 00 to ff.

Android ShapeDrawable stroke is blurred

I created a rather simple shapedrawable with semi-transparent borders, and used it as a background for two adjacent view.
Either if the srtoke color is partially transparent, I'm expecting a solid stroke (like the image on the right), but what I get is a blurred stroke (image on the left).
What I'm doing wrong?
(images are taken from the ADT preview, in the emulator the effect is even more visible)
This is the ShapeDrawable (theme_base_bg_framed.xml):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#color/base_frame_solid_color"
/>
<stroke
android:width="#dimen/frame_border_size"
android:color="#color/base_frame_border_color"
/>
<padding
android:left="#dimen/frame_padding_size"
android:top="#dimen/frame_padding_size"
android:right="#dimen/frame_padding_size"
android:bottom="#dimen/frame_padding_size"
/>
</shape>
It uses these color and dimen definitions:
<color name="base_frame_solid_color">#20ffffff</color>
<color name="base_frame_border_color">#40ffffff</color>
<dimen name="frame_border_size">2dp</dimen>
<dimen name="frame_padding_size">2dp</dimen>
Both drawables are assigned to the Views background
<style name="ViewWithBorder">
<item name="android:background">#drawable/theme_base_bg_framed</item>
</style>
Edit:
The colors used in the ShapeDrawable are alphaed for a reason. The view in the background is going to contain other views and/or images. This is a better example of what I get (left) and what I'm expecting to get (right).
I use this values to get the result you wanted:
colors.xml:
<color name="base_frame_solid_color">#20000000</color>
<color name="base_frame_border_color">#40ffffff</color>
shape:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#color/base_frame_solid_color"
/>
<stroke
android:width="#dimen/frame_border_size"
android:color="#color/base_frame_border_color"
/>
</shape>
Hope this helps!
Ok, I found what's happening and how to fix it.
It seems that Android, when filling a ShapeDrawable with a border, doesn't fill it to it's full size but just to the middle of the stroke. So, with a stroke of 2dp, it leave a space of 1dp all around. This can be noticed only when using alphaed borders, like I'm doing, because normally the border cover it.
Tho fix this behaviour, I used a LayerList drawable containing two ShapeDrawables, one for the solid color (with no borders) and one for the stroke (with no solid color):
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid
android:color="#color/base_frame_solid_color"
/>
</shape>
</item>
<item>
<shape
android:shape="rectangle">
<stroke
android:width="#dimen/frame_border_size"
android:color="#color/base_frame_border_color"
/>
<padding
android:left="#dimen/frame_padding_size"
android:top="#dimen/frame_padding_size"
android:right="#dimen/frame_padding_size"
android:bottom="#dimen/frame_padding_size"
/>
</shape>
</item>
</layer-list>
It works, but being the border superimposed to the "solid" background, it's color need some adjustment.

android layer-list header and footer

I am trying to create a background drawable for a linearlayout that has multiple gradients.
E.g. I want to have a gradient at the top and bottom, and a solid color in the middle. So basically a header and footer.
I am trying to use a layer-list like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<!--Red-->
<item>
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#ff0000" />
</shape>
</item>
<!-- Green -->
<!-- Offsets from the top and bottom -->
<item
android:top="20dp"
android:bottom="20dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#00ff00" />
</shape>
</item>
<item
android:top="80dp">
<!--Blue -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#0000ff" />
</shape>
</item>
</layer-list>
The problem is, I am unsure of the max value of density independant pixels. For this to work, the bottom item offest would need to be (max dp value-20). I have tried to assume the max is 100, and also assume the max is 160 (from the documentation), but neither of these work.
Any ideas?

Categories

Resources