XML drop shadow and different states - android

I'm trying to define a background for my ListView that has drop shadow and different colours for pressed state. Here's what I have.
<?xml version="1.0" encoding="utf-8"?>
<!-- Drop Shadow Stack -->
<item>
<shape>
<padding android:bottom="1dp"/>
<solid android:color="#00CCCCCC" />
</shape>
</item>
<item>
<shape>
<padding android:bottom="1dp" />
<solid android:color="#10CCCCCC" />
</shape>
</item>
<item>
<shape>
<padding android:bottom="1dp" />
<solid android:color="#20CCCCCC" />
</shape>
</item>
<item>
<shape>
<padding android:bottom="1dp" />
<solid android:color="#30CCCCCC" />
</shape>
</item>
<item>
<shape>
<padding android:bottom="1dp" />
<solid android:color="#50CCCCCC" />
</shape>
</item>
<!-- Background -->
<item android:state_pressed="true">
<shape>
<solid android:color="#color/fublue" />
</shape>
</item>
<item android:state_activated="true">
<shape>
<solid android:color="#color/fublue" />
</shape>
</item>
<item>
<shape>
<solid android:color="#color/white" />
</shape>
</item>
However, that doesn't work. What do I need to change to get it working?

I'm not entirely sure what you're doing for the drop-shadow, but for the press states, you must make your list view item layouts clickable. And then create a background selector drawable for your push states.
Standard Style File
yourcolorstates.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:platformrq="http://schemas.android.com/apk/res-auto" >
<item
android:background="#yourneutralcolor"
android:state_pressed="false" />
<item
android:background="#yourpressedcolor"
android:state_pressed="true" />
</selector>

wrap the items in a state selector and the states need to be be set.
example
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true">
<shape>
...
</shape>
</item>
</selector>

Related

Removing ripple tag from XML crashes the app

I have next xml background file
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<ripple android:color="#color/backgroundColorPrimary">
<item>
<selector>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="#android:color/transparent" />
<stroke
android:width="#dimen/button_border_width"
android:color="#26E7E7E7" />
<corners android:radius="7dp" />
</shape>
</item>
<item android:state_selected="false">
<layer-list>
<item
android:left="3dp"
android:top="1dp">
<shape>
<corners android:radius="7dp" />
<solid android:color="#26E7E7E7" />
</shape>
</item>
<item
android:top="2dp"
android:bottom="4dp"
android:left="2dp"
android:right="1dp">
<shape>
<corners android:radius="7dp" />
<solid android:color="#color/white" />
</shape>
</item>
</layer-list>
</item>
</selector>
</item>
</ripple>
</inset>
Ripple effect goes beyond the margins of the button I put this background to. I guess it is because of this part of code:
android:top="2dp"
android:bottom="4dp"
android:left="2dp"
android:right="1dp">
which makes shadow on my button. I would like to make ripple effect only on the original size of button. How should I do this.
Also removing ripple tag crashes my app. I can add in the place of ripple, but then it does not work as I want it to.
How to solve this?

Setting a Buttons background programmatically from drawable folder incorrectly makes button background black

I am creating buttons dyanmically for a gridview, however I want to apply a drawable background presented below. However the background is black, but on pressed appears correctly.
I have a button created called roundedge_button_dark.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape android:shape="rectangle" >
<corners android:radius="6dip" />
<gradient android:angle="-90" android:startColor="#3f3f3f" android:endColor="#a6a6a6" />
</shape>
</item>
<item android:state_focused="true">
<shape android:shape="rectangle" >
<corners android:radius="6dip" />
<solid android:color="#ff0000"/>
</shape>
</item>
<item>
<shape android:shape="rectangle" >
<corners android:radius="6dip" />
<gradient android:angle="-90" android:startColor="#0F0F0F" android:endColor="#000000" />
</shape>
</item>
</selector>
I'm accessing said drawable button like so:
button.setBackgroundResource(R.drawable.roundedge_button_dark);
The problem I have is that the image shows black, which is the end colour for the non state defined item; What am I missing or is this not possible?
Try this,
<item android:state_pressed="true">
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="2dp" android:color="#ff0000" />
<solid android:color="#ffff00" />
<padding android:bottom="2dp" android:left="5dp" android:right="5dp" android:top="2dp" />
<corners android:radius="5dp" />
</shape>
</item>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="2dp" android:color="#ff0000" />
<solid android:color="#FF6699" />
<padding android:bottom="2dp" android:left="5dp" android:right="5dp" android:top="2dp" />
<corners android:radius="5dp" />
</shape>
</item>
or try this,
first create your drawable xml file for button states:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Button Pressed-->
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/rounded_button_click_effect"
/>
<!-- Button Default Image-->
<item android:drawable="#drawable/rounded_button"/>
</selector>
after that create rounded_button_click_effect.xml file in case of button click:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" >
<corners android:radius="6dip" />
<gradient android:angle="-90" android:startColor="#3f3f3f" android:endColor="#a6a6a6" />
</shape>
</item>
</layer-list>
and finally create rounded_button.xml file in case of default state:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" >
<corners android:radius="6dip" />
<gradient android:angle="-90" android:startColor="#0F0F0F" android:endColor="#000000" />
</shape>
</item>
</layer-list>

Change Padding in Selector drawable

i am trying to change the padding from a Button in a custom drawable ressource, and reuse this in a selector.
Changing the drawable seems not the Problem, but the App always use the highest padding aviable from the different drawables:
button_inactive.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="#FF4d681f" />
</shape>
</item>
<item
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp">
<shape android:shape="rectangle" >
<solid android:color="#FFFFFFFF" />
<padding
android:bottom="5dp"
android:top="5dp" />
</shape>
</item>
button_active.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="#FF4D681F" />
</shape>
</item>
<item
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp">
<shape android:shape="rectangle" >
<solid android:color="#FF8da32d" />
<padding
android:bottom="10dp"
android:top="10dp" />
</shape>
</item>
button_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="#drawable/button_active"/>
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/button_active"/>
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/button_active"/>
<item android:drawable="#drawable/button_inactive"/>
The Problem is that my Button uses the 10dp padding in all states, including the "inactive" state.
Is there a Solution to get it working only with XML or it is better to make a custom Button programaticly?
try this
<solid android:color="#ffffff" />
<stroke
android:width="2dp"
android:color="#android:color/black" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
<corners
android:bottomLeftRadius="6dp"
android:bottomRightRadius="6dp"
android:topLeftRadius="6dp"
android:topRightRadius="6dp" />
Add android:variablePadding="true" attribute to your selector.
I'm not sure how (and if) is this working when you are using layer-list, however I decided to share it anyway for anyone looking for the answer (as I was).

How to border only left, top and bottom for TextView

Here is my coding. Here is design blue color for TextView's 4 border. What I want is to design only for 3 borders (top, left and bottom).
<?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="#449def" />
<stroke
android:width="1dp"
android:color="#2f6699" />
<corners
android:radius="0dp" />
<padding
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#2f6699" />
<corners
android:radius="0dp" />
<padding
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
</selector>
Below code placed at the bottom of height of 1dp, you have to play with this for other sides
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
<shape>
<solid android:color="#535353" />
</shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
<shape>
<solid android:color="#252525" />
</shape>
</item>
</layer-list>
Refer this discussion Open-sided Android stroke?
This is a quick solution (probably dumb), add android:translationX="2dp" on your TextView and you can add android:paddingRight="2dp" to make up for lost space.
Try like this
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<padding android:bottom="1dp" android:left="1dp" android:right="0dp"
android:top="1dp"/>
<solid android:color="#000"/>
</shape>
</item>
<!-- Background -->
<item>
<shape>
<solid android:color="#color/white"/>
</shape>
</item>
</layer-list>

Android selector with background image and gradient

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.

Categories

Resources