I was wondering if it is possible to have multiple borders/"stroke" elements on a shape, or if I need to use an image (or a bunch of shapes covering each other). My code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:endColor="#color/editTextBG"
android:startColor="#color/editTextBG"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#color/editTextEdgeInner" />
<stroke
android:width="1dp"
android:color="#color/editTextEdgeCenter" />
<stroke
android:width="1dp"
android:color="#color/editTextEdgeOuter" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
I've tried just using the code, which didn't work, and giving the earlier strokes a bigger width (so that the later, if drawn over, would only color part). However, it seems the last stroke overrides the others?
A workaround for borders is to overlay elements:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="#color/colorAccent"/>
</item>
<item android:top="8dp">
<color android:color="#color/colorPrimaryDark"/>
</item>
<item android:top="16dp">
<color android:color="#color/colorPrimary"/>
</item>
<item android:top="32dp" android:right="8dp">
<color android:color="#android:color/holo_red_dark"/>
</item>
</layer-list>
This is the result:
The first element in the layer-list from top to bottom is the background and every other is mounted on top.
<item>
<shape android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#color/colorWhite" />
<stroke
android:width="1dp"
android:color="#979797" />
</shape>
</item>
<item
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp">
<shape android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="#ffd400" />
</shape>
</item>
Related
I currently have the following drawable which creates a rectangle with rounded edges, a semi-transparent black background and transparent edges (in case I want to show them later):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="#android:color/transparent" />
</item>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#50FFFFFF"/>
<stroke
android:width="5dip"
android:color="#android:color/transparent" />
<corners android:radius="30dp" />
</shape>
</item>
</layer-list>
My question is how could I modify this so that the edges of the rectangle's background fade, to give a softer appearance?
I did something like this for work once.
Just make a layer-list with multiple rectangle each with increasing opacity and padding
code below:
<?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="#03101010" />
<corners android:radius="24dp" />
</shape>
</item>
<item
android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp">
<shape android:shape="rectangle">
<solid android:color="#06101010" />
<corners android:radius="20dp" />
</shape>
</item>
<item
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape android:shape="rectangle">
<solid android:color="#09101010" />
<corners android:radius="16dp" />
</shape>
</item>
<item
android:bottom="12dp"
android:left="12dp"
android:right="12dp"
android:top="12dp">
<shape android:shape="rectangle">
<solid android:color="#12101010" />
<corners android:radius="12dp" />
</shape>
</item>
</layer-list>
The number of layers may vary depending on the color of your primary rectangle and the background.
I have a button and a selector that must change color, padding and corner radius of the button. I have no problems with changing the color, but I can never see any changes with padding and corner radius.
button_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/button_disabled" android:state_enabled="false">
<shape
android:shape="rectangle"
android:padding="8dp">
<corners android:radius="4dp" />
</shape>
</item>
<item android:drawable="#color/button_pressed" android:state_pressed="true">
<shape
android:shape="rectangle"
android:padding="8dp">
<corners android:radius="4dp" />
</shape>
</item>
<item android:drawable="#color/button_focused" android:state_focused="true">
<shape
android:shape="rectangle"
android:padding="8dp">
<corners android:radius="4dp" />
</shape>
</item>
<item android:drawable="#color/colorAccent">
<shape
android:shape="rectangle"
android:padding="8dp">
<corners android:radius="4dp" />
</shape>
</item>
</selector>
code of the button:
<LinearLayout>
....
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/add_to_fav"
android:id="#+id/add"
android:background="#drawable/button_color"
android:textColor="#drawable/button_text_color" />
</LinearLayout>
I know some clumsy way to get the padding - put it into the layout, but 1) it would be "useless parent"; 2) I wouldn't get corner radius.
So what am I doing wrong so I have not shape?
Thanks!
Padding, color and corners should be inside shape
So try this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false">
<shape>
<padding android:left="5dp" android:top="2dp"
android:right="5dp" android:bottom="2dp" />
<corners android:radius="4dp" />
<solid android:color="#color/colorPrimary"/>
</shape>
</item>
<item android:state_pressed="true">
<shape>
<padding android:left="5dp" android:top="2dp"
android:right="5dp" android:bottom="2dp" />
<corners android:radius="4dp" />
<solid android:color="#color/colorAccent"/>
</shape>
</item>
<item android:state_focused="true">
<shape>
<padding android:left="5dp" android:top="2dp"
android:right="5dp" android:bottom="2dp" />
<corners android:radius="4dp" />
<solid android:color="#color/colorPrimary"/>
</shape>
</item>
<item>
<shape>
<padding android:left="5dp" android:top="2dp"
android:right="5dp" android:bottom="2dp" />
<solid android:color="#color/colorPrimaryDark"/>
<corners android:radius="4dp" />
</shape>
</item>
</selector>
This way all of them will work.
The android:radius value was probly just too small for the effect to be visible. The syntax for the padding on the other hand has to be changed like this:
<item android:drawable="#color/button_focused" android:state_focused="true">
<shape
android:shape="rectangle">
<corners android:radius="20dip" />
<padding
android:left="8dip"
android:top="8dip"
android:right="8dip"
android:bottom="8dip" />
</shape>
</item>
Please note: as stated in the documentation for Shape Drawable,
Padding to apply to the containing View element (this pads the position of the View content, not the shape).
I would like to create a custom XML layout for my TextView, using rounded corners and a custom header, such as this example.
I found this very useful link that creates the following quite similar result.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Bottom 2dp Shadow -->
<item>
<shape android:shape="rectangle">
<solid android:color="#d8d8d8" />
<corners android:radius="7dp" />
</shape>
</item>
<!-- White Top color -->
<item android:bottom="3px">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="7dp" />
</shape>
</item>
</layer-list>
I wonder if it possibile to modify the XML layout above to get the header "ADD FRIEND" style, that is the darker gray background and the divider between the header textview ("ADD FRIEND") and the textview below (the one containing the "Nickname or email" and the "search" button).
I am thinking it is probably easier to do it with an image/drawable background, but getting it done in XML would be awesome (in terms of reusability for example).
Any help or suggestion on how to proceed is very welcome!
if you not using image for that then require three xml in drawable and create this type of layout :
1 linearlayout_background.xml
<?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="#CABBBBBB" />
<corners android:radius="2dp" />
</shape>
</item>
<item
android:bottom="2dp"
android:left="0dp"
android:right="0dp"
android:top="0dp">
<shape android:shape="rectangle" >
<solid android:color="#android:color/white" />
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
header_background :
<item><shape>
<padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp" />
<corners android:topLeftRadius="5dp" android:topRightRadius="5dp" />
<solid android:color="#color/off_black1" />
</shape></item>
buttonbackground
<item><shape>
<padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp" />
<corners android:radius="5dp" />
<solid android:color="#00000000" />
<stroke android:width="1dp" android:color="#color/off_white2" />
</shape></item>
I know there are similar post to this but I couldn't find my answer in any of them. So, I have this drawable XML:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true">
<bitmap
android:src="#drawable/bm_btn_background"
android:tileMode="repeat"
android:gravity="center" />
</item>
<item android:state_enabled="true">
<shape android:shape="rectangle">
<gradient
android:startColor="#a0e0b071"
android:endColor="#a0a67637"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#5c3708" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#a0a67637"
android:endColor="#a0e0b071"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#5c3708" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
I am trying to create a button with a repeated image as background and a gradient applied to it. With this code I only see the background image, not the gradient nor the border and the rounded corners. Also, when I click the button, it doesn't change (the gradient is supposed to change). I don't know what is wrong with this code? If instead of a selector I use a layer-list, I get the desired result but it doesn't change either when I press the button. Thanks for your help!
Your code for the selector is wrong because:
You have two elements for the same state and as the selector encounters the first state(state_enabled) for the Bitmap element it will stop there and your gradient will never appear(for this you should use a layer-list that has as items the Bitmap and the gradient on top)
The selector will match states in order. As you press the Button the state_pressed will never be activated because the selector will match first the state_enabled that is on the first element(for this you should move the code for the state_pressed above the state_enabled elements).
In fact you should just remove the state_enabled and let the Bitmap + gradient be the default value for the Button. Bellow is your selector(I assumed you only want to change gradient on the image(but the image should appear even in the pressed state, if this isn't the wanted behavior leave only the gradient for the state_pressed)):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<layer-list>
<item>
<bitmap android:gravity="center" android:src="#drawable/bm_btn_background" android:tileMode="repeat" />
</item>
<item>
<shape>
<gradient android:angle="270" android:endColor="#a0e0b071" android:startColor="#a0a67637" />
<stroke android:width="1dp" android:color="#5c3708" />
<corners android:radius="5dp" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
</layer-list>
</item>
<item android:state_enabled="true">
<layer-list>
<item>
<bitmap android:gravity="center" android:src="#drawable/bm_btn_background" android:tileMode="repeat" />
</item>
<item>
<shape android:shape="rectangle">
<gradient android:angle="270" android:endColor="#a0a67637" android:startColor="#a0e0b071" />
<stroke android:width="1dp" android:color="#5c3708" />
<corners android:radius="5dp" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
</layer-list>
</item>
</selector>
Take a look on your state attrubute
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:drawable="#drawable/nicebuttonround" android:state_focused="false" android:state_pressed="false" android:state_selected="false"/>
<item android:drawable="#drawable/nicebuttonround" android:state_focused="false" android:state_pressed="false" android:state_selected="true"/>
<!-- Focused states -->
<item android:drawable="#drawable/nicebuttonroundi" android:state_focused="true" android:state_pressed="false" android:state_selected="false"/>
<item android:drawable="#drawable/nicebuttonroundi" android:state_focused="true" android:state_pressed="false" android:state_selected="true"/>
<!-- Pressed -->
<item android:drawable="#drawable/nicebuttonroundi" android:state_pressed="true" android:state_selected="true"/>
<item android:drawable="#drawable/nice22i" android:state_pressed="true"/>
</selector>
For repeating background as image you just have to create 9 pitch images.
in my case i am using this. try it
<item android:state_pressed="true">
<shape>
<solid android:color="#color/mediumGray" />
<stroke
android:width="1px"
android:color="#color/darkGray" />
<padding
android:bottom="2dp"
android:left="1dp"
android:right="1dp"
android:top="2dp" />
<corners
android:bottomLeftRadius="7sp"
android:bottomRightRadius="7sp"
android:topLeftRadius="7sp"
android:topRightRadius="7sp" />
</shape>
</item>
<item android:state_focused="true">
<shape>
<solid android:color="#color/mediumGray" />
<stroke
android:width="1px"
android:color="#color/darkGray" />
<padding
android:bottom="2dp"
android:left="1dp"
android:right="1dp"
android:top="2dp" />
<corners
android:bottomLeftRadius="7sp"
android:bottomRightRadius="7sp"
android:topLeftRadius="7sp"
android:topRightRadius="7sp" />
</shape>
</item>
<item>
<shape>
<solid android:color="#color/lightGray" />
<stroke
android:width="1px"
android:color="#color/blackTransparent" />
<padding
android:bottom="2dp"
android:left="1dp"
android:right="1dp"
android:top="2dp" />
<corners
android:bottomLeftRadius="7sp"
android:bottomRightRadius="7sp"
android:topLeftRadius="7sp"
android:topRightRadius="7sp" />
</shape>
</item>
I have added extra transperent space to the right side of image using photoshop canvas size option and it works fine for me. download below image to see demo.
I've made a button background from shapes and is looking quite good for my purpose. The only thing needed is to drop a bit of shadow for it.
Here is the code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#343434" />
<stroke android:width="1dp" android:color="#171717" />
<corners android:radius="3dp" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
<item>
<shape>
<gradient android:angle="270" android:endColor="#E2E2E2" android:startColor="#BABABA" />
<stroke android:width="1dp" android:color="#BABABA" />
<corners android:radius="4dp" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
</selector>
Here's what I want to achieve
How do I drop the shadow ? My guess is that I need to make another shape but with black/gray background and set some sort of topa nd left padding of margin to make it look like a shadow. But I don't know how to do it... and documentation didn't helped me too much.
Later Edit: I want to add the shadow in xml file and not by code.
Thanks.
If you want to stack more shapes one on top of each other then you could use a layer-list. Bellow is the code for the normal item in your selector(with a strip of gray color):
<item>
<layer-list>
<item android:right="5dp" android:top="5dp">
<shape>
<corners android:radius="3dp" />
<solid android:color="#D6D6D6" />
</shape>
</item>
<item android:bottom="2dp" android:left="2dp">
<shape>
<gradient android:angle="270" android:endColor="#E2E2E2" android:startColor="#BABABA" />
<stroke android:width="1dp" android:color="#BABABA" />
<corners android:radius="4dp" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
</layer-list>
</item>
The problem is that you'll not be able to achieve a true shadow look on your Button with this type of drawable. You could use the code from the other answer or a nine patch image that already has shadow on it.
Try this...
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape>
<solid android:color="#000000" />
<corners android:radius="7dp" />
</shape>
</item>
<item
android:bottom="5px"
android:left="5px">
<shape>
<solid android:color="#FF0000" />
<corners android:radius="7dp" />
</shape>
</item>
</layer-list>
Paint mShadow = new Paint();
// radius=10, y-offset=2, color=black
mShadow.setShadowLayer(10.0f, 0.0f, 2.0f, 0xFF000000);
// in onDraw(Canvas)
canvas.drawBitmap(bitmap, 0.0f, 0.0f, mShadow);
This code is from Android's Romain Guy available here : http://www.devoxx.com/download/attachments/1705921/D8_C_10_09_04.pdf
You may try this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Bottom Shadow Darker Line-->
<item>
<shape android:shape="rectangle" >
<solid android:color="#color/blue_darker" />
<corners android:radius="9dip" />
</shape>
</item>
<!-- Main Content Gradient -->
<item android:bottom="1dip">
<shape android:shape="rectangle" android:dither="false" >
<gradient
android:startColor="#color/blue_dark"
android:centerColor="#color/blue_medium"
android:endColor="#color/blue_light"
android:type="linear"
android:angle="90"/>
<corners android:radius="9dip" />
</shape>
</item>
<!-- Upper Shadow Dark Line -->
<item android:bottom="1dip" android:left="1dip" android:right="1dip">
<shape android:shape="rectangle" >
<gradient
android:centerX="0.98"
android:centerY="0"
android:startColor="#android:color/transparent"
android:centerColor="#android:color/transparent"
android:endColor="#color/blue_medium"
android:type="linear"
android:angle="90"/>
<corners android:radius="9dip" />
</shape>
</item>
you can try the following code also to get a smooth border shadow for view:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape>
<solid android:color="#88000000" />
<corners android:radius="15dp" />
</shape>
</item>
<item
android:bottom="5px"
android:right="5px">
<shape>
<solid android:color="#55B0CF" />
<stroke
android:width="2dp"
android:color="#ffffff" />
<corners android:radius="7dp" />
</shape>
</item>
In this case I use lib https://github.com/dmytrodanylyk/shadow-layout
Firstly, you should turn on it in gradle
dependencies {
compile 'com.github.dmytrodanylyk.shadow-layout:library:1.0.3'
}
then put your Button into ShadowLayout
<com.dd.ShadowLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:sl_shadowRadius="3dp"
app:sl_shadowColor="#color/your_color">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.dd.ShadowLayout>
It's worsk great for me)