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.
Related
i'm currently working with the camera api and want to implement a button, which starts and stops video recordings. the button has four different images: video_start_default, video_start_pressed, video_stop_default and video_stop_pressed.
it should change its layout when pressed and after starting/stopping the video.
i created this xml file to do so.
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/video_start_default" />
<item
android:state_selected="false"
android:state_pressed="true"
android:drawable="#drawable/video_start_pressed" />
<item
android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/video_stop_default" />
<item
android:state_selected="true"
android:state_pressed="true"
android:drawable="#drawable/video_stop_pressed" />
<item android:drawable="#drawable/video_default" />
</selector>
in order to make the change between start and stop work, i set the select attribute in the onclicklistener
if(videoButton.isSelected())
videoButton.setSelected(false);
else{
videoButton.setSelected(true);
}
basically this works.
while pressing video_start_default, video_start_pressed is correctly shown but the problem is that after releasing video_start_pressed, video_stop_pressed is shown for a millisecond instead of video_stop_default. strangely the problem doesn't occure after clicking video_stop_pressed. here is video_start_default directly visible.
i hope the description is not to confusing
I think you have to make two selectors one for the play state and another for the pause state:
I have a nice tutorial for you that can help you a lot in your project
you have to see this link.
Cheers
I made a layout that is just simply a textview that says "What do you want?", followed by a series of buttons underneath it.
All of the buttons can be clicked/touched, but when I scroll with the trackball, none of them become highlighted. I noticed, however, then when I disable the background colors on the buttons, I can see the orange box that shows that button's focus.
Is there any way I can visibly see the focus while still being able to have a background color on the buttons?
EDIT: Found the solution! This helped A LOT. Standard Android Button with a different color
Create a "selector" resource in your res/drawable. It can look something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#color/white" />
<item
android:state_pressed="true"
android:drawable="#color/orange" />
<item
android:state_selected="true"
android:state_pressed="false"
android:drawable="#color/blue" />
</selector>
Then set the background of your button to be:
android:background="#drawable/your_selector"
Rather than applying a simple background color to buttons, try applying a ColorStateList instead.
To do so, define a new XML file at
/res/color/buttonstate.xml
and use code such as the following:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="# FOCUSED COLOR HERE"
android:state_focused="true" />
<item android:drawable="# DEFAULT COLOR HERE" />
</selector>
Notes:
You can definitely add more colors for more states, such as pressed, enabled, and certain other factors.
In the layout or code just reference R.color.buttonstate or #color/buttonstate (the XML's filename).
Make sure the default color is last. This is because it goes down the list and finds the first item that has all of the states the same as it. If you don't provide android:state_focused="false" for the default item and put it first, it will always display.
You can do a similar thing with drawables and
nine-patch drawables to make your own custom button styles.
Rather than just change the background color, consider using a 9-patch style. This is more work to begin, but you'll have much more control over your app's appearance.
Modify your Button layout to look something like this (the style line is the kicker):
<Button
style="#style/PushButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Your styles.xml resource file then should contain a style similar to this:
<style name="PushButton">
<item name="android:background">#drawable/btn</item>
</style>
Then the btn.xml (put in in res/drawable) contents should look something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/btn_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/btn_focused"
android:state_pressed="false"
android:state_focused="true" />
<item android:drawable="#drawable/btn_default"
android:state_focused="false"
android:state_pressed="false" />
You would then use some image editor to create files named btn_pressed.9.png, btn_focused.9.png, and btn_default.9.png. Drop these files in your res/drawable.
A good starting point is the Google IO app (I lifted the code examples from it). Just grab the png files and modify them to match your desired style.
Keep in mind you can put all sorts of stuff in the style now, like text size, height and width.
In an android app, I have a GridView holding TextView created by an adapter. In those TextView I add an icon which has three states (pressed, selected and default.)
I removed the default selector of the GridView with android:listSelector="#00000000" and I would like the selected state of the icon to display instead. But although the pressed state works (ie when the TextView is pressed, the pressed version of the icons is shown) the seleted doesn't.
I've tried those tricks (found at different places on the web) but it didn't work either:
setting
android:descendantFocusability="afterDescendants"
or
android:drawSelectorOnTop="true"
or (in the TextViews)
android:duplicateParentState="true" />
And if I set the TextView to be focusable, it gets focus independently of the GridView (ie, clicking on it doesn't call the GridView onClick method...)
The icon is defined in a xml file like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="#drawable/ic_flag_bg_pressed"/>
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/ic_flag_bg_pressed"/>
<item android:state_focused="true"
android:drawable="#drawable/ic_flag_bg_selected"/>
<item android:state_focused="false"
android:state_pressed="false"
android:drawable="#drawable/ic_flag_bg_default"/>
</selector>
Is there a way to tell the GridView to pass the focused state to its children ?
Got stuck on this as well. An alternate approach that can look okay is to use a border style selector and draw it on top.
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.
I'm setting a selector.xml to the ListView Selector :
<item android:state_focused="false" android:state_selected="true"
android:state_pressed="true" android:drawable="#drawable/timeline_selected_rect"/>
<item android:state_focused="false" android:state_selected="true"
android:state_pressed="false" android:drawable="#drawable/timeline_selected_rect"/>
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="true" android:drawable="#drawable/timeline_selected_rect"/>
but setting this is causing the TextView flickr over selection. this thing is not happening when the Default selector is used... whats wrong with this selector.
I have even added android:cacheColorHint="#00000000" as provided info by some other blogs.
I recently ran into this problem as well and found the solution by analyzing the Android source code.
You need to remove the android:state_selected="true" attributes since checking that state is unneeded. Once a list item loses it's focus, it also makes 'selected = false'. Since focus=false & selected=true will never occur, your first 2 <items> in the selector will never be shown.
Think of the tap like a mouse click with an onPressDown and onPressUp event.
So your new selector.xml should looks something like this to avoid the flickering:
<!-- {comment copied directly from Android source code}
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_pressed="true" android:state_focused="true"
android:drawable="#drawable/timeline_selected_rect"/>
<item android:state_pressed="true" android:state_focused="false"
android:drawable="#drawable/timeline_selected_rect" />
<item android:state_focused="true"
android:drawable="#drawable/timeline_selected_rect" />
<item android:state_window_focused="false"
android:drawable="#android:color/transparent" />
As an aside, you should seriously consider creating a separate drawable for the pressed state so that you give a bit of visual feedback. It is always nicer to see "something happen" when interacting with the UI; whether that is drawing a button in a "down" state while it is being pressed or changing the color slightly while tapping on a list item, the visual feedback is good practice.