How can I have an imagebutton stay in the 'pressed' state when it is clicked? Basically I just want the background to be the depressed background, but I can't figure out how to set it. At the moment, I've just copied the selected button background into my res folder, but when I set it as the background, it becomes blurry (since the original image is bigger than the button itself).
Normal Background:
alt text http://img707.imageshack.us/img707/9199/ss20100426163452.png
What I'm getting:
alt text http://img707.imageshack.us/img707/912/ss20100426163357.png
alt text http://img3.imageshack.us/img3/8304/ss20100426163623.png
Also I don't believe I can actually use this method considering the many different UI layouts. The button should stay pressed as per the UI the user is using.
There are a few ways of doing this:
First, you can simply use an ImageButton, and manually toggle its image drawable on click in Java. This is what the stock Music player on Android does for the shuffle button, for example. Although you won't have control over the button background in its checked state, you'll be able to swap out the image, which may be favorable from an Android UI-consistency perspective.
Another option is to use a complex set of drawables and nine-patches to get an image inside a ToggleButton, with the option of changing the background and/or the image resource upon toggle. That's the option I'll show below. But remember, be cautious about UI consistency before doing this.
res/layout/foo.xml
...
<ToggleButton
android:textOn="" android:textOff=""
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/shuffle_button" />
...
res/drawable/shuffle_button.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- use "#android:drawable/btn_default" to keep consistent with system -->
<item android:drawable="#drawable/toggle_button_background" />
<item android:drawable="#drawable/shuffle_button_image" />
</layer-list>
res/drawable/toggle_button_background.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- checked state -->
<item android:state_pressed="false" android:state_checked="true"
android:drawable="#drawable/btn_default_checked" />
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="#drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="#drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="#drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="#drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="#drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="#drawable/btn_default_normal_disable_focused" />
<item android:drawable="#drawable/btn_default_normal_disable" />
</selector>
res/drawable/shuffle_button_image.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_mp_shuffle_on_btn" android:state_checked="true" />
<item android:drawable="#drawable/ic_mp_shuffle_off_btn" />
</selector>
Image files
btn_default_<state>.9.png can be found in frameworks/base.git
under
core/res/res/drawable-hdpi
and
core/res/res/drawable-mdpi (also ldpi).
WARNING: if you use these, your app will look inconsistent on devices with customized OS UIs (i.e. HTC's Sense UI).
ic_mp_shuffle_<state>_btn.9.png need to be nine-patches, so that the image gets centered and not stretched to fit the button. Below are example hdpi versions of the icon:
res/drawable-(h|m|ldpi)/ic_mp_shuffle_(on|off)_btn.9.png
Final Note: Remember to be consistent with the system UI when possible, and be mindful of the fact that your app may run on devices with customized versions of the OS that have different graphics for UI elements like buttons. An example of this is HTC Sense, which has green buttons in place of the grey/orange/yellow ones in stock Android. So, if you end up copying the btn_default_... PNG files from the open source repository to create a toggle-able button background, you'll break consistency on those devices.
Related
In iOS, one code line is enough to have button show touch highlight: yourButton.showsTouchWhenHighlighted = YES;
In Android, selector could be used. However, it's quite tedious. For example, if there're 100 button icons in my app, I have to prepare at least 200 button icons: 100 for normal and 100 for highlighted.
Is there any convenient/simpler way to do this?
You may try Ripple Effect to show touch effect
Create a single selector, and use that as a background for all your views (this doesn't need to be created for each button individually, you can apply the same one universally).
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#000000" /> <!-- pressed -->
<item android:state_focused="true"
android:color="#000000" /> <!-- focused -->
<item android:color="#FFFFFF" /> <!-- default -->
</selector>
This can be applied universally to ALL your buttons like this:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/button_selector" />
There is a new Ripple response, but this is available for Android 5.0 devices plus (there probably is a 3rd party library on GitHub allowing this to work on earlier OSes)
I'm trying to create complex drawable with one picture inside changing with main view state change. My current resource looks like that
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item >
<layer-list>
<item>
<selector>
<item android:state_activated="true" android:drawable="#drawable/img_activated_icon" />
<item android:drawable="#drawable/img_default_icon" />
</selector>
...
Next I use it as src for my ImageView.
The whole drawable renders fine but the selector ignores setActive() call on the ImageView and always displays "default" icon.
What am I doing wrong?
UPD
So, here goes the desired drawable hierarchy:
layer-list
transition
background1
background2
image
I was unable to activate transition animation in this case so I moved the transition to the upper level:
transition
layer-list
background1
image
layer-list
background2
image (the same image!)
So, how can I implement the first layout and be able both to control the transition and to change source for the image?
So basically you want to be able to control the drawables manually, and have them react to state changes. To my knowledge, it is bad practice to try to set a fake state (pressed/focused/etc) on a View, so I would recommend you don't try to do that. I haven't done this before, but I can't see why it couldn't be done. My idea would be to create a single LevelList of StateLists for this button/image.
The LevelList would provide you to have control over what "theme" the button/image has depending on the level you set it to using setLevel(). Each level would point to a "themed" StateList that would have different "themed" drawables for all the various states (pressed/focused/etc).
http://developer.android.com/guide/topics/resources/drawable-resource.html#LevelList
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="0" android:drawable="#drawable/state_list_icon_default" />
<item android:maxLevel="1" android:drawable="#drawable/state_list_icon_another_style_1" />
<item android:maxLevel="2" android:drawable="#drawable/state_list_icon_another_style_2" />
</level-list>
Your state_list_icon_default would have your default drawables, like this (it's up to you what states you want to have drawables for):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/img_default_icon_pressed" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="#drawable/img_default_icon_focused" />
<item android:state_enabled="false" android:state_focused="true" android:drawable="#drawable/img_default_icon_disabled_focused" />
<item android:state_enabled="false" android:drawable="#drawable/img_default_icon_disabled" />
<item android:drawable="#drawable/img_default_icon"/>
</selector>
Here's some tutorials to see more in depth implementations.
http://iserveandroid.blogspot.com/2010/10/progress-bar-implementation-using-level.html
http://sermojohn.wordpress.com/2012/02/04/using-a-state-list-drawable-as-a-button-background-image/
On Android application How can I get the glow effect on button when touched; I am looking for exact similar effect like ipod/iphone buttons
Use a StateListDrawable. Type this into a file and store it as res/drawable/button_bg.xml. Then create 4 images button_press.png, button_focus.png, button_disabled.png and button.png and last set your background to button_bg. If you want your button glow when touch you can add an image of your glowing button to state press. So when you press the system will get glowing_button.png and display it.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_press" android:state_pressed="true" />
<item android:drawable="#drawable/button_focus" android:state_focused="true" />
<item android:drawable="#drawable/button_disabled" android:state_enabled="false" />
<item android:drawable="#drawable/button" />
</selector>
The "magic" behind this is that android will go from the top to bottom and use the first one matching your buttons state.
In these links you can find some snippets to get exactly the same TabBar as iOS applications
iPhone Tab in Android
TabHost For Android
iTabs
I am writing an extremely simple Android application. In doing so, I've found it's quite difficult for me to emulate the button UI elements that are found on the Droid X application selector screen. For those not familiar, they are an icon with white text beneath them. The text has a black rounded rectangle behind it and when the button is clicked, the background beneath the icon and text turns red.
My current solution involves StateListDrawables, but then the rounded rectangle has a fixed width, and has to be edited into every button icon. Localization is an eventual goal, so my solution is temporary at best. I assume there's a less stupid way to do this?
I haven't tried this, and I've never seen the button you're talking about. But the process should be something similar.
First you create your drawables (the actual background images). One with the red background and one transparent. Your drawable XML would look something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/btn_bg_red"/>
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/btn_bg_red"/>
<item android:state_focused="true" android:drawable="#drawable/btn_bg_pressed"/>
<item android:state_focused="false" android:state_pressed="false" android:drawable="#android:color/transparent"/>
</selector>
Then your button itself can be declared similar to this:
<Button android:id="#+id/droid_x_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Droid Does"
android:drawableTop="#drawable/btn_icon" <!-- this is for the icon on top -->
android:background="#drawable/ic_droid_x_button" <!-- The name of the above file without extension -->
android:textColor="#color/white" />
Hope this helps!
I am trying to setup a selector drawable in my asset file like this:
* 2 different images for 'on'/'off' mode in rest mode (i.e. it does
not has focus)
* another 2 different images for 'on'/'off' mode in focus mode (i.e.
it has the focus).
In my case, the 'rest' mode works, but the 'focus' mode does not.
Can you please tell me what am I missing in the focus mode? Thank you.
<!-- these 2 images works --->
<item android:state_checked="false" android:drawable="#drawable/off" />
<item android:state_checked="true" android:drawable="#drawable/on" />
<!-- these 2 images does not work -->
<item android:state_focused="true" android:state_checked="false"
android:drawable="#drawable/off_focus" />
<item android:state_focused="true" android:state_checked="true"
android:drawable="#drawable/on_focus" />
I don't believe that instances of ImageView are focusable by default, meaning that they would never take focus and your selector would never be triggered. In the place where you define your ImageView you need to set it to be focusable, see these methods: setFocusable and setFocusableInTouchMode. It can be set from XML or in code.