Currently, I have the following bottom log in button.
When button is not being pressed
When button is being pressed
The XML looks like this
<LinearLayout
android:background="?attr/welcomeBottomNavBarBackground"
android:orientation="horizontal"
android:id="#+id/sign_in_bottom_nav_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
style="?android:attr/buttonBarButtonStyle"
android:id="#+id/sign_in_button"
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="1.0"
android:layout_height="48dp"
android:gravity="center"
android:layout_gravity="center"
android:enabled="true"
android:textAllCaps="true"
android:text="#string/log_in" />
</LinearLayout>
I would like to remove the padding (Or should I call it margin? Please refer to my bottom most p/s section) around button when it is being pressed.
I look at How to remove padding around buttons in Android?
I had tried
<Button
...
...
android:minHeight="0dp"
android:minWidth="0dp" />
It doesn't work and has no effect.
I further try
<Button
...
...
android:background="#null"
android:minHeight="0dp"
android:minWidth="0dp" />
No more padding when pressed. However, the material designed pressed visual effect will gone too.
May I know what is the best way to remove button padding during pressed, yet retain the material designed pressed visual effect?
P/S
I don't really know whether I should call it padding or margin. What I wish to achieve is that, when we press on the bottom region, press visual effect change should be covered entire 100% bottom bar region (#+id/sign_in_bottom_nav_bar), instead of current 95% bottom bar region.
A standard button is not supposed to be used at full width which is why you experience this.
Background
If you have a look at the Material Design - Button Style you will see that a button has a 48dp height click area, but will be displayed as 36dp of height for...some reason.
This is the background outline you see, which will not cover the whole area of the button itself.
It has rounded corners and some padding and is supposed to be clickable by itself, wrap its content, and not span the whole width at the bottom of your screen.
Solution
As mentioned above, what you want is a different background. Not a standard button, but a background for a selectable item with this nice ripple effect.
For this use case there is the ?selectableItemBackground theme attribute which you can use for your backgrounds (especially in lists).
It will add a platform standard ripple (or some color state list on < 21) and will use your current theme colors.
For your usecase you might just use the following:
<Button
android:id="#+id/sign_in_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
android:background="?attr/selectableItemBackground" />
<!-- /\ that's all -->
There is also no need to add layout weights if your view is the only one and spans the whole screen
If you have some different idea on what your background should look like you have to create a custom drawable yourself, and manage color and state there.
As simple, use the inset property like:
android:insetTop="0dp"
android:insetBottom="0dp"
android:insetRight="0dp"
android:insetLeft="0dp"
In styles.xml
<style name="MyButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">#drawable/selector</item>
<item name="android:textColor">#android:color/black</item>
</style>
In values/drawable:
my_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="2dp" />
<!-- specify your desired color here -->
<solid android:color="#9e9b99" />
</shape>
selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="#drawable/my_drawable"/>
<item android:state_pressed="true" android:drawable="#drawable/my_drawable"/>
<item android:drawable="#android:color/transparent"/>
</selector>
In values/drawable-v21:
my_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
android:tint="?attr/colorButtonNormal"
xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="2dp" />
<solid android:color="#android:color/white" />
</shape>
selector.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:id="#android:id/mask"
android:drawable="#drawable/my_drawable" />
</ripple>
In layout:
<Button
android:id="#+id/button"
style="#style/MyButtonStyle"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="Test"/>
Result on API 19:
Result on API 21:
Source code
I think the best solution to solve that is create your own Ripple Effect. The padding when you press the button is respecting the default Ripple Effect of the component.
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>
Or you can try change the style of your button to style="?android:textAppearanceSmall"
Remember: This effect is only shown on Android Lollipop (API 21) or higher.
I have been through what you are going through. Long story short, you just cannot do it cleanly with a <Button> tag alone, while ensuring backwards compatibility.
The simplest and the most widely practiced method is to use a <RelativeLayout> underlay, around a <Button>.
Button Code:
<RelativeLayout
android:id="#+id/myButtonUnderlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:visibility="visible">
<Button
android:id="#+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:text="I am as cute as a Button"/>
</RelativeLayout>
Wherever you need to use a button, you use this complete code.
Here is the breakdown:
OnClick events will be hooked to myButton.
Control dimensions of your button, by changing attributes of myButtonUnderlay.
In myButton, android:background="?attr/selectableItemBackgroundBorderless". This will make it a transparent button with just the text, and backwards compatible ripples.
In myButtonUnderlay, you will do all the other background applications, like setting the color of the button, margins, paddings, borders, gradients, and shadows etc.
If manipulation of the button's visibility (programmatic or not) is wish, you do it on myButtonUnderlay.
Note: To ensure backwards compatibility, make sure that you use
android:background="?attr/selectableItemBackgroundBorderless", and NOT
android:background="?android:attr/selectableItemBackgroundBorderless"
As #David Medenjak answer you can read the Google Material design Button-style to its developer site. Use button style as #David Medenjak explained in his answer. You can also do by the following way also
It is not a padding or margin but it is actually background effect of button.
If you want to remove that then you can do as following.
Option 1:
Step 1: Put the below code in styles.xml
<style name="myColoredButton">
<item name="android:textColor">#FF3E96</item>
<item name="android:padding">0dp</item>
<item name="android:minWidth">88dp</item>
<item name="android:minHeight">36dp</item>
<item name="android:elevation">1dp</item>
<item name="android:translationZ">1dp</item>
<item name="android:background">#FF0000</item>
</style>
Step 2:Create a new XML file under drawables folder and add the following code: I named my XML file as button_prime.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorPrimary">
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp" />
<solid android:color="#8B8386" />
</shape>
</item>
</ripple>
Step 3: Use the style and drawable in your Button as follows.
<Button
style="#style/myColoredButton"
android:layout_width="250dp"
android:layout_height="50dp"
android:text="Cancel"
android:gravity="center"
android:background="#drawable/button_prime"
android:colorButtonNormal="#3578A9" />
Option 2:
With the Support Library v7, all the styles are actually already defined and ready to use, for the standard buttons, all of these styles are available.So you can set your button style like this
<Button
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="BUTTON"
android:gravity="center"
android:minHeight="0dp"
android:minWidth="0dp"
android:background="#color/colorAccent"/>
For more detail of Button style please check this answer
I think you will check this answer also. I hope you will get your solution.
The padding and margin may be a result of the original resources used in the button.
So you could try to change the resources used, using a selector:
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/btn_action_hover" />
<item android:state_selected="true" android:drawable="#drawable/btn_action_hover" />
<item android:state_focused="true" android:drawable="#drawable/btn_action_hover" />
<item android:drawable="#drawable/btn_action_normal" />
</selector>
That would change the default images/shapes for your buttons, so you could try using drawables and set every item to a drawable. The drawable being either a bitmap, or a .xml file(style file) defining the look of the button in its current state. I assume there still are some native styles included even though you have set the button-style yourself. This may be because you aren't using a custom theme. So the issue may also be solved by defing
theme="#style/myNewTheme"
where myNewTheme is your theme, and it should have any parents(parent="" should not be defined).
Take any given theme(designed by Google/Android, for an instance Theme.AppCompat.[name]), it does also come with a buttonStyle. This is a part of Theme.Holo.Light:
<!-- Button styles -->
<item name="buttonStyle">#style/Widget.Holo.Light.Button</item>
<item name="buttonStyleSmall">#style/Widget.Holo.Light.Button.Small</item>
<item name="buttonStyleInset">#style/Widget.Holo.Light.Button.Inset</item>
<item name="buttonStyleToggle">#style/Widget.Holo.Light.Button.Toggle</item>
<item name="switchStyle">#style/Widget.Holo.Light.CompoundButton.Switch</item>
<item name="mediaRouteButtonStyle">#style/Widget.Holo.Light.MediaRouteButton</item>
<item name="selectableItemBackground">#drawable/item_background_holo_light</item>
<item name="selectableItemBackgroundBorderless">?attr/selectableItemBackground</item>
<item name="borderlessButtonStyle">#style/Widget.Holo.Light.Button.Borderless</item>
<item name="homeAsUpIndicator">#drawable/ic_ab_back_holo_light</item>
As you see, this theme defines how your buttons will look/work in basic features. You can override parts of it, but you haven't overridden the important parts(being buttonStyle and similar). So if you create a new theme yourself and style it to your liking and set the theme(using theme="themename") and that theme does not inherit any theme, you should be able to style your buttons to your liking without having to worry about the default styles in the theme
Basically:
calling padding/margin="0dp" will not help. The default drawable defined by the theme has this in the button drawable, meaning you cannot change it. So you have to either change the button style, or change the theme completely. Make sure that theme does not have any parents, because many themes define the button style. You do not want the button style defined by the theme.
The best solution these days is just to use MaterialButton in place of Button.
Note: MaterialButton is visually different from Button and AppCompatButton. One of the main differences is that AppCompatButton has a 4dp inset on the left and right sides, whereas MaterialButton does not. To add an inset to match AppCompatButton, set android:insetLeft and android:insetRight on the button to 4dp, or change the spacing on the button’s parent layout.
When replacing buttons in your app with MaterialButton, you should inspect these changes for sizing and spacing differences.
Source: https://material.io/develop/android/components/material-button/
I'd suggest you taking a look at this just in case before all.
Then, if not working i'd suggest you to create your own style (like azizbekian suggest)using android xml drawables, and drawable states to differentiate pressed/notpressed.
I think using your own style may be the best answer as it will further give you more control on how your app is displaying, but using android default themes and styles also allows the user to have custom styles which is a good idea. However, you cannot test every custom style so you cannot check that your app will display correctly on ALL custom styles, and therefore may encounter problems with some.
Set the Button background as android:background="?selectableItemBackground"
<LinearLayout
android:background="?attr/welcomeBottomNavBarBackground"
android:orientation="horizontal"
android:id="#+id/sign_in_bottom_nav_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
style="?android:attr/buttonBarButtonStyle"
android:background="?selectableItemBackground"
android:id="#+id/sign_in_button"
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="1.0"
android:layout_height="48dp"
android:gravity="center"
android:layout_gravity="center"
android:enabled="true"
android:textAllCaps="true"
android:text="#string/log_in" />
</LinearLayout>
After trying lots of solution, Finally I came to a conclusion that with tag alone we can't achieve this. to remove this unwanted space around button my solution is as below:
<RelativeLayout
android:id="#+id/myButtonUnderlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:visibility="visible">
<Button
android:id="#+id/save_button"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="-5dp"
android:layout_marginBottom="-5dp"
android:layout_above="#+id/content_scrollview"
android:layout_gravity="bottom"
android:background="#drawable/ripple_theme"
android:enabled="true"
android:text="SetUp Store"
android:textColor="#fff"
android:textSize="18sp"
android:visibility="gone"
tools:visibility="visible"
style="#style/MediumFontTextView" />
</RelativeLayout>
1.add a drawable resource file named maybe button_background.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="#ff0000"/>
<stroke android:width="5dp" android:color="#00ff00"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#00ff00"/>
</shape>
</item>
</selector>
2.Use the button_background.xml as the button background, done!
github
blog
I don't really know whether I should call it padding or margin.
The button is enacting surface elevation for providing visual feedback in response to touch. It is one of two feedbacks used for surface reaction; the first one being the ripple effect. For example, a raised button has resting state elevation of 2dp and pressed state elevation of 8dp (See raised button under Shadows). The button meets the finger as it touches the surface.
May I know what is the best way to remove button padding during pressed, yet retain the material designed pressed visual effect?
Having answered the first part, I do not believe you are having all of the material design if you wish to remove the surface elevation effect.
Anyways, here is how to remove surface elevation visual feedback:
Add animator file button_raise.xml to animator directory under res directory having the following code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="true"
android:state_pressed="true">
<objectAnimator
android:duration="#android:integer/config_shortAnimTime"
android:propertyName="translationZ"
android:valueTo="0dp"
android:valueType="floatType" />
</item>
</selector>
Refer newly created animator in the button using stateListAnimator property:
<Button
...
android:stateListAnimator="#animator/button_raise"
... />
Hope this helps.
Related
I am using the following code to make a star button:
<Button
android:id="#+id/leftButton"
android:onClick = "Star"
android:layout_width="100dp"
android:layout_height="100dp"
android:Color="#FFFF00" //I tried adding this, but no luck :(
android:layout_alignParentTop="true"
android:background="#android:drawable/btn_star" />
The button currently looks white:
Is there anyway I can make it yellow?
I know I can't have two background attributes, but is there anything I can do to change the color of this star? I want to keep the star as a background attribute, rather than a source attribute, because I want to be able to change the size of it.
If you want to yellow the star icon, then you can use ColorFiler for this. As follows:
Drawable drawable = getResources().getDrawable(android.R.drawable.star);
drawable.setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
Hope this helps.
Not directly. You can add different colorized images and change them at runtime, but much better way is to use a xml drawable. For icons with xml files take a look at https://materialdesignicons.com (there are much more sites like that outside)
In the xml file you can change the color directly
Your xml file.
<Button
android:id="#+id/leftButton"
android:tint="#color/yellow_tint"
android:onClick = "Star"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:background="#android:drawable/btn_star" />
colors.xml
<resources>
<color name="yellow_tint">#FFFF00</color>
</resources>
Try it and let me know. Refer to this: Working with Drawables. I'm afraid android:color won't work in Drawables.
(background_star.xml) on drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/star_yellow" <!-- image yellow -->
android:state_pressed="true" />
<item android:drawable="#drawable/star_normal" /> <!-- image normal-->
</selector>
on layout file:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="cancel alarm"
android:id="#+id/button2"
android:background="#drawable/background_star" <!-- change this -->
android:layout_centerHorizontal="true" />
I'm trying to change the color of my switch in Android. I realize that I will need new 9patches. I went over to http://android-holo-colors.com/ and selected my color and selected (Switch Jelly Bean). To use Switch Jelly Bean I had to use: https://github.com/BoD/android-switch-backport. To import it into my project I had to add:
<item name="switchStyle">#style/Widget.Holo.CompoundButton.Switch</item>
to my styles, and then in xml I have to use the switch like so:
<org.jraf.android.backport.switchwidget.Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Now everything with the switch works fine. Next, I took everything that was output from the android holo color generator and put it into the proper files:
drawable (2 selector files)
drawable-hdpi (9patch files)
drawable-xhdpi (9patch files)
drawable-xxhdpi (9patch files)
then I added to my xml:
<org.jraf.android.backport.switchwidget.Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:thumb="#drawable/apptheme_switch_inner_holo_light"
android:track="#drawable/apptheme_switch_track_holo_light" />
but it is still the original blue color. I believe I'm doing everything correctly. Everything compiles (xml, java). Note: I AM importing org.jraf.android.backport.switchwidget.Switch in my java also. Any ideas?
As per this, (direct answer by BoD copy-paste):
You must not use android:thumb and android:track, but instead, app:thumb and app:track And you must add the following to the root of your xml document:
xmlns:app="http://schemas.android.com/apk/res-auto"
Easiest way in Android Lollipop and above,
<style name="AppTheme" parent="MaterialTheme.Light">
...
<item name="android:colorControlActivated">#color/color_switch</item>
</style>
for androidx.swithcomapact use
app:thumbTint="#color/purple_700"
app:trackTint="#color/purple_700"
Try this:
switch_thumb.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:drawable="#drawable/switch_thumb_holo_light" />
<item android:state_pressed="true" android:drawable="#drawable/switch_thumb_activated_holo_light" />
<item android:state_checked="true" android:drawable="#drawable/switch_thumb_activated_holo_light" />
<item android:drawable="#drawable/switch_thumb_holo_light" />
</selector>
In the layout of the switch:
android:thumb="#drawable/switch_thumb"
to change the color of switch you can use two images
green - when switch is ON
red - when switch is OFF
now put this file in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/blue_checked" android:state_checked="true"/>
<item android:drawable="#drawable/blue_unchecked" android:state_checked="false"/>
</selector>
and in the layout XML file use it as below
<CheckBox
android:id="#+id/user_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/notif_checkbox_selector"
/>
It might be that you need to put
style="#style/switchStyle"
in your XML as well
How can I set the star color of the ratingbar? I want yellow stars.
The simpliest way:
android:progressTint="#color/color"
Smooth and shiny.
This worked for me:
Drawable drawable = ratingBar.getProgressDrawable();
drawable.setColorFilter(Color.parseColor("#FFFDEC00"), PorterDuff.Mode.SRC_ATOP);
I've found that just setting the progressTint is not a complete solution. It will change the color of the star but not on partial star fills if your stepSize is less than 1. In my experience you also need to set the secondaryProgressTint in order to stop the default star tint from rearing its ugly head. Here is my code:
android:progressTint="#color/accent"
android:secondaryProgressTint="#android:color/transparent"
Hope this helps someone in my situation.
Have you tried an xml theme, such as
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#android:id/background"
android:drawable="#drawable/star_empty_show"/>
<item
android:id="#android:id/secondaryProgress"
android:drawable="#drawable/star_empty_show"/>
<item
android:id="#android:id/progress"
android:drawable="#drawable/star_filled_show"/>
</layer-list>
calling it in your xml as
<RatingBar
android:id="#id/rate"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5.0dip"
android:isIndicator="true"
android:max="5"
android:numStars="5"
android:progressDrawable="#drawable/ratebar_theme"
android:stepSize="0.1" />
and using your own drawables?
You do need 3 star images (star_filled_show.png, star_half_show.png and star_empty_show.png) and one xml, that's all.
Put these 3 images into res/drawable.
Put there the following ratingbarstars.xml:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#android:id/background"
android:drawable="#drawable/star_empty_show"/>
<item
android:id="#android:id/secondaryProgress"
android:drawable="#drawable/star_half_show"/>
<item
android:id="#android:id/progress"
android:drawable="#drawable/star_filled_show"/>
</layer-list>
Tell your ratingbar definition to use this drawable
<RatingBar android:progressDrawable="#drawable/ratingbarstars.xml"/>
The rating bar is used automatically at run time for change color on touch star.
First add style in app\src\main\res\values\styles.xml file:
<style name="RatingBar" parent="Theme.AppCompat">
<item name="colorControlNormal">#color/duskYellow</item>
<item name="colorControlActivated">#color/lightGrey</item></style>
Then your rating bar add theme like this:
<RatingBar
android:id="#+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:stepSize="1"
android:theme="#style/RatingBar"/>
It's a little complicated at the mentioned blog, I've used a similar but simplier way. You do need 3 star images (red_star_full.png, red_star_half.png and red_star_empty.png) and one xml, that's all.
Put these 3 images at res/drawable.
Put there the following ratingbar_red.xml:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background" android:drawable="#drawable/red_star_empty" />
<item android:id="#android:id/secondaryProgress" android:drawable="#drawable/red_star_half" />
<item android:id="#android:id/progress" android:drawable="#drawable/red_star_full" />
</layer-list>
and, finally, tell your ratingbar definition to use this, i.e.
<RatingBar android:progressDrawable="#drawable/ratingbar_red"/>
That's it.
try this one
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW,PorterDuff.Mode.SRC_ATOP);
When I did it, and I had to put the TintMode too.
<RatingBar
android:progressTint="#color/colorAccent"
android:progressTintMode="src_atop" ---- This is important!
android:secondaryProgressTint="#color/colorPrimary"
android:secondaryProgressTintMode="src_atop" ---- This is important!
android:progressBackgroundTint="#color/black_alpha"/>
only for api version 21 and above
<RatingBar
android:id="#+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/RatingBar"/>
with theme in styles
<style name="RatingBar" parent="Theme.AppCompat">
<item name="colorControlNormal">#color/gray</item>
<item name="colorControlActivated">#color/yellow</item>
I'd like to change the background for an image button. Basically the image I have looks great on a transparent background and a bit lousy when there are a bunch of them all with a non-transparent background.
This should be easy - just change the android:background on the button to a transparent color (via a drawable):
click_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"><color android:color="#FF008080" />
</item>
<item android:state_pressed="true"><color android:color="#FF008080" />
</item>
<item><color android:color="#00000000" />
</item>
</selector>
Then the button
<ImageButton
android:id="#+id/players"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:background="#drawable/click_background"
android:contentDescription="#string/players"
android:src="#drawable/speaker_tile" />
The problem is that I actually want to retain the state_focussed and state_pressed versions of the background (which I presume is derived from the theme). I would like to have the background appear when the button is pressed or selected (and appear with the exact same colour/drawable) that would be used by the theme normally when a button is pressed would be helpful.
I was wondering if there is a way to do one of the following, but have so far been unable to find anything on either:
Define a selector that in some what inherits from another (similar to the way a theme can inherit from another).
Create an entirely new selector but have it's XML reference the color/drawable of the theme's state_focussed and state_pressed used for an image button. Edit: It looks like this option is out. I would have needed attributes, but you can't reference them from a drawable. See here
I'd like to do this in Declarative XML rather than Programmatic Java if possible.
You can copy the drawables used by the Android OS into your project and use them in your state-list drawable. You can find the images in {android-sdk-directory}/platforms/android-##/data/res/drawable[-*dpi]
EDIT:
If you go to {android-sdk-directory}/platforms/android-##/data/res/values, you'll find the themes.xml and styles.xml files used by Android. Using them you can figure out which drawables you'll be looking for.
For example, the default theme on newer versions of Android is Theme.Holo. This theme has a default style for ImageButtons declared like so:
<item name="imageButtonStyle">#android:style/Widget.Holo.ImageButton</item>
In styles.xml, this style is defined as follows:
<style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
<item name="android:background">#android:drawable/btn_default_holo_dark</item>
</style>
Thankfully the background attribute is right there defined in plain sight. Sometimes it's inherited from a parent style and you have to find that instead. In any case, here's the drawable (found in the /drawable directory since it's 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>
So those are the drawables Android uses for the background of a standard ImageButton in the default (holo dark) theme.
I have an image button set up like so:
<ImageButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/navup"
android:layout_weight="33"
android:layout_margin="5dip"
android:src="#drawable/up_button_icon"
android:background="#drawable/up_button" />
"#drawable/up_button_icon" is a png.
/res/drawable/up_button.xml:
<?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/up_button_press" />
<item
android:drawable="#drawable/up_button_norm" />
</selector>
The "press" states are png's that have a sunken look to them. Think of hitting a button on your tv's remote control.
The button is rendered correctly, however there is a problem when the button is pressed. The up_icon image stays stationary. For a better UI, the icon should shift down 2px so that it follows the "sunken" background.
Ideally, I would like to set this up through the XML layouts, but I am open to code solutions as well.
I think making a sunken version of the icon too and create another StateListDrawable could be a solution.