Android - State Selector Animations - Only animate de-press, NOT press - android

I have a very basic selector that I am using as the background for some buttons to achieve down states. Here's the xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item android:drawable="#color/home_button_blue_down" android:state_selected="true" />
<item android:drawable="#color/home_button_blue_down" android:state_pressed="true" />
<item android:drawable="#color/home_button_blue" />
</selector>
With this selector the fade animation will occur every time the button changes state. In other words, the transition will animate both when going from de-pressed to pressed and also when going back from pressed to de-pressed.
Now, my question is: is it possible to make it so that only one of these state changes animates? When a user presses the button, I want the downstate transition to occur immediately without animations. When the button becomes de-pressed, I want the downstate to fade out while the normal state fades back in. Can this be done?

Animations on selector : (my drawables were colors )
De-Press (Out)
android:exitFadeDuration="#android:integer/config_shortAnimTime"
Press (In)
android:enterFadeDuration="#android:integer/config_shortAnimTime"
Full example:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="#android:integer/config_shortAnimTime"
android:exitFadeDuration="#android:integer/config_shortAnimTime">
<item android:state_checked="false" android:drawable="#color/transparent"/>
<item android:state_checked="true" android:drawable="#drawable/circle_blue"/>
</selector>

You can do something like this:
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/selected"
android:state_selected="true"
android:drawable="#color/home_button_blue_down"
/>
<item android:id="#+id/usual"
android:drawable="#android:color/transparent"
/>
<transition
android:fromId="#+id/usual"
android:toId="#+id/selected" >
<animation-list>
<!--fill in your animation here-->
</animation-list>
</transition>
</animated-selector>
Keep in mind animated-selector is available only after API 21.
More info in this official guide

<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="#android:integer/config_shortAnimTime"
android:exitFadeDuration="#android:integer/config_longAnimTime">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#ffffff"
android:endColor="#917777"
android:angle="270" />
</shape>
</item>
<item android:state_pressed="false" >
<shape>
<gradient
android:startColor="#ffffff"
android:endColor="#d2adad"
android:angle="270" />
</shape>
</item>
<item android:state_checked="true">
<color android:color="#color/black"/>
</item>
</selector>

Related

Android button color change on pressed

When you create an android button, the original color is grey. when you press it, the color changes, when you release it, it goes back to it's original grey.
that's what I would like to do with mine, but with other colors than the default grey. The problem is, when I change the color of my button then I click on it, nothing happens, as if I was clicking on an empty layout.
Here's the XML file i wrote to solve my problem - button_connexion_style.xml
?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#ff0000ff" android:state_focused="true" /> <!-- focused -->
<item android:color="#449D44"/> <!-- default -->
<item android:drawable="#278727" android:state_pressed="true"/>
</selector>
In my button XML code I do this to call the previous XML :
android:background="#drawable/button_connexion_style"
But it doesn't work.
If anyone can help, please let me know.
flat_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/rect_pressed"/>
<item android:drawable="#drawable/rect_normal"/>
</selector>
rect_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/rect_pressed" />
<item android:bottom="#dimen/layer_padding">
<shape android:shape="rectangle">
<corners android:radius="#dimen/corner_radius" />
<solid android:color="#color/colorPrimary" />
</shape>
</item>
</layer-list>
rect_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="#dimen/corner_radius" />
<solid android:color="#color/colorPrimaryDark" />
</shape>
add below line in your button
android:background="#drawable/flat_selector"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#color/red" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#color/blue" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#color/green" />
<item
android:state_enabled="true"
android:drawable="#color/grey" />
</selector>
Create an xml file in your drawable like above,
And set images/color accordingly and then set this xml as background of your imageButton.
Please do fill with according to your color code,
button_connexion_style.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/green" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="#color/blue" android:state_focused="true" /> <!-- focused -->
<item android:drawable="#color/default_green" /> <!-- default -->
</selector>
and add these color code in values colors ,
<color name="blue">#ff0000ff</color>
<color name="green">#278727</color>
<color name="default_green">#449D44</color>
You are almost right just one thing you miss default should always last statement
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#ff0000ff" android:state_focused="true" /> <!-- focused -->
<item android:drawable="#278727" android:state_pressed="true"/>
<item android:drawable="#color/yourDefaultColor" />
</selector>
let me know if not work

Android drawable: state_selected working, superseding state_pressed?

Newbie in Android.
I have the following defined in res/drawable/ for a button in a menu that's defined in style.xml
<style name="menu_icon">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">#dimen/menu_item_height</item>
<item name="android:background">#drawable/menu_item_bg_sel</item>
</style>
Now, menu_item_bg_sel in drawable has two different color gradients for 2 states that I am interested in- pressed and selected.
<?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>
<shape>
<gradient android:angle="180"
android:endColor="#color/background_menu_gray_selected2"
android:centerColor="#color/background_menu_gray_selected1"
android:startColor="#color/background_menu_gray_selected" />
</shape>
</item>
</layer-list>
</item>
<item android:state_selected="true">
<layer-list>
<item>
<shape>
<gradient android:angle="180" android:endColor="#color/background_menu_home2"
android:centerColor="#color/background_menu_home1"
android:startColor="#color/background_menu_home" />
</shape>
</item>
</layer-list>
</item>
<item android:drawable="#color/transparent"/>
However, when I press the button (that transient state) the button still creates the gradient taking colors from the selected_state only.
What am I doing wrong? Any ideas?
state_selected is commonly used when navigating using d-pads or maybe a pen like what Samsung Notes so I suggest not to use state_selected since when you press automatically it will be selected or gain focus although selected and focus are kind or different. I suggest to use state_pressed, state_focused and state_hovered instead.
For more info click here
You can use this code. You can copy paste this code into one drawable file. You can assign different drawable files or define shapes in this file itself for the different states.I have assigned a drawable file for the focused state as an example.
simple_button_states.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
android:drawable="#drawable/rounded_edittext_focused"
/>
<!--pressed -->
<item
android:state_pressed="true" />
<!--selected -->
<item
android:state_selected="true" />
<!-- focused -->
<item
android:drawable="#drawable/rounded_edittext_unfocused"/>
</selector>
round_edittext_focused.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
>
<solid android:color="#FFFFFF" />
<stroke
android:width="2dp"
android:color="#color/CornflowerBlue" />
<corners
android:topLeftRadius="4dp"
android:topRightRadius="4dp"
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp"
/>
</shape>
Finally assign the background of the actual button as the drawable file that you have declared above.
<Button
android:layout_width="150dp"
android:layout_height="wrap_content"
android:background="#drawable/simple_button_states"
/>
Hope this helps

Android: make list item with background clickable

I have a list where I have defined my own list view items with a custom layout. This layout has a background with a custom drawable.
My custom layout for the ListView item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/item"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true" >
...
</RelativeLayout>
My custom drawable item.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- background: shadow -->
<item>
<shape
android:dither="true"
android:shape="rectangle" >
<corners android:radius="2dp" />
<solid android:color="#color/itemShadowColor" />
</shape>
</item>
<!-- foreground: surface -->
<item android:bottom="2dp">
<shape
android:dither="true"
android:shape="rectangle" >
<corners android:radius="2dp" />
<solid android:color="#color/itemBackgroundColor" />
</shape>
</item>
</layer-list>
Now this item is not clickable anymore.
Can you explain me why, and what I have to do to have the same behavior (selector with the blue background) like a button click?
Define a selector with its pressed and default states in res/drawable folder(one of the state will be your #drawable/item). Set it as the bg of your list row layout.
See similar question and answer :Selector on background color of TextView
Edit:
Best way to understand and apply something like google did is, to look into SDK and do similar things to that. For instance look at the btn_default_holo_dark drawable. It is a selector with states and yes it is a xml.
This is a selector taken from sdk (sdk\platforms\android-18\data\res\drawable\btn_default_holo_dark.xml)
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="#drawable/btn_default_normal_holo_dark" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="#drawable/btn_default_disabled_holo_dark" />
<item android:state_pressed="true"
android:drawable="#drawable/btn_default_pressed_holo_dark" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="#drawable/btn_default_focused_holo_dark" />
<item android:state_enabled="true"
android:drawable="#drawable/btn_default_normal_holo_dark" />
<item android:state_focused="true"
android:drawable="#drawable/btn_default_disabled_focused_holo_dark" />
<item
android:drawable="#drawable/btn_default_disabled_holo_dark" />
</selector>
These are the images taken from sdk (sdk\platforms\android-18\data\res\drawable-xhdpi):
When you apply this drawable/selector (#drawable/btn_default_holo_dark) to any view, you are going to have its states. I hope this sample makes my answer more clear.

Custom tabs are not responding to pressed state

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#drawable/tab_profile_pressed_mdpi" />
<item android:drawable="#drawable/tab_profile_unselected_mdpi" />
</selector>
And how I set them:
((ImageView)tabHost.getTabWidget().getChildTabViewAt(i).findViewById(R.id.single_tab_img)).setImageResource(unselected_img[i]);
You need to use setBackgroundResource not setImageResource. State drawables work on the background image, not the foreground image.
I believe you need another xml file that lays out what will happen when the tab is pressed.
Example:
tab.xml
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="false" android:drawable="#drawable/tab_bg_selected" />
tab_bg_selected
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:startColor="#A8A8A8" android:centerColor="#7F7F7F"
android:endColor="#696969" android:angle="-90" />
</shape>

Android: How to achieve the glow effect when long-pressing a list item?

With the default selector, long-pressing a list item causes its background to transition between two colors.
Replacing the selector with the one below removes the effect. According to this question, I need an animation to reproduce it. How would I go about doing that in xml?
<?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="#color/state_pressed" />
</shape>
</item>
<item
android:state_focused="true">
<shape>
<solid
android:color="#color/state_focused" />
</shape>
</item>
<item>
<shape>
<solid
android:color="#color/state_idle_grey" />
</shape>
</item>
</selector>
Here is the code from list_selector_background :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:drawable="#android:color/transparent" />
<!--
Even though these two point to the same resource, have two states so
the drawable will invalidate itself when coming out of pressed state.
-->
<item android:state_focused="true" android:state_enabled="false"
android:state_pressed="true" android:drawable="#drawable/list_selector_background_disabled" />
<item android:state_focused="true" android:state_enabled="false"
android:drawable="#drawable/list_selector_background_disabled" />
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/list_selector_background_transition" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/list_selector_background_transition" />
<item android:state_focused="true"
android:drawable="#+drawable/list_selector_background_focus" />
</selector>
Found on the web.
And it uses this transition for long press clicks :
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/list_selector_background_pressed" />
<item android:drawable="#drawable/list_selector_background_longpress" />
</transition>
Found on the web too .
There is no animation for that. And remember to keep you states in the same order, or at least think about it if you swap them, order is important.
Personnally, I like when things behave in a standard way, so I would just let the standard list selector.
Regards,
Stéphane

Categories

Resources