Why isn't my ImageButton style being applied to my ImageButton? - android

I have some styles set up to work on different API's (one for v21 and one for anything below that). I want to have a style for my ImageButton but it doesn't seem to be working out the way I expect.
The style for the v-21 is
<style name="BorderlessImageButton" parent="AppTheme.BorderlessImageButton">
<item name="android:background">?android:attr/selectableItemBackgroundBorderless</item>
<item name="android:tint">#color/secondary_text</item>
</style>
The style that will be used for all other API's below v-21 is
<style name="BorderlessImageButton" parent="AppTheme.BorderlessImageButton"/>
<style name="AppTheme.BorderlessImageButton" parent="#android:style/Widget.ImageButton">
<item name="android:tint">#color/secondary_text</item>
<item name="android:background">#color/borderless_button_background</item>
</style>
Here is my xml resource
<ImageButton
android:id="#+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="#id/date_picker"
android:background="#null"
android:padding="10dp"
android:src="#drawable/ic_today_white_24dp"
android:theme="#style/BorderlessImageButton" />
If I run this on a device that has v-21 or v-22, the button doesn't visually react to my touch as I would expect using the ?android:attr/selectableItemBackgroundBorderless. Also, on any device below v-21, the button still doesn't react to the selector resource I have set up for it.
res/color/borderless_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" android:color="#color/accent" />
<item android:color="#color/transparent"/>
</selector>
Please help me get my button to react properly to touch based on which API the user has on their device.
Thanks

You need to apply your style with
style="#style/BorderlessImageButton"
The attribute android:theme is used for activities, see this.
UPDATE
Since Android 5.0, or using AppCompat 22.1.0+ (api 11+), you can also use a ThemeOverlay and use android:theme on single views. You can read about this technique here. Thanks to Ian for this.

Related

How to color button background when it is disabled

I want to color my button that is defined in a fragment. I created new style (which I use as a theme in the button) and defined "colorAccent" for enabled state, "colorButtonNormal" for disabled and parent of this style is "Widget.AppCompat.Button". I want it to be coloured exactly as it is written in colorButtonNormal when button is disabled.
<style name="Material.Button.Primary" parent="#style/Widget.AppCompat.Button">
<item name="android:colorButtonNormal">#color/color_disabled</item>
<item name="colorAccent">#color/color_primary</item>
</style>
<Button
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/button_text"
android:textAppearance="#style/AppTheme.Text"
android:theme="#style/Material.Button.Primary" />
When the button is enabled it has correct color from colorAccent. When user clicks on it, it becomes disabled and should be gray (#b2b2b2) but it becomes a little bit lighter (#E7E7E7). It seems like it takes color that I defined and mixes with white color.
I tried to change style's parent and did some changes in style and button's attributes as it is written in some guides from the internet but nothing worked. My current solution is to set colorButtonNormal to #000000. When button is disabled, it becomes #B9B9B9.
Forgive me if I am wrong but as far I understand correctly, you want to achieve different colours for enabled/disabled states.
UPDATE
For keeping the material effect you can use styling with Widget.AppCompat.Button.Colored and create theme with specified colours:
<Button
.
.
.
style="#style/Widget.AppCompat.Button.Colored"
android:theme="#style/CustomButton"/>
And create theme, where colorButtonNormal is for disabled state
<style name="CustomButton" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">#color/color_disabled</item>
<item name="colorAccent">#color/color_enabled</item>
</style>
Old without material effect
You can try using selector like:
custom_button.xml
<?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/color_disabled" />
<item android:state_enabled="true" android:drawable="#color/color_enabled/>
</selector>
and then in your xml for button:
<Button
.
.
.
android:background="#drawable/custom_button" />

Error inflating ImageView / ImageButton with ColorStateList tint value

Using an ImageView / ImageButton (AppCompatImageView / AppCompatImageButton) in conjunction with a style attribute of android:tint which makes use of a ColorStateList resource works fine on >= API 21, but throws an InflateException on API < 21.
Firstly, I don't even know whether the AppCompatImageView / (Button) tinting supports ColourStateList xml resources as an android:tint value, I can't seem to find a definitive answer to this. Suggestions I can find on S/O suggest implementing a TintableImageView etc, but these answers are quite dated, and it seems from the source of the appcompat implementations this should be a feature.
To clarify this is definitely the issue. Removing the android:tint attribute or setting it to a single colour resource works.
Also to clarify, I'm aware this is achievable programmatically. I'm trying to get it backwards compatible in xml.
Minimal example
activity_foo.xml
<android.support.v7.widget.AppCompatImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_caret_up"
style="#style/IconButton.Primary"
/>
styles.xml
<style name="IconButton.Primary">
<item name="android:tint">#color/link_button_color</item>
</style>
link_button_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/btnLinkPressedTextColor"
android:state_selected="true" />
<item android:color="#color/btnLinkPressedTextColor"
android:state_pressed="true" />
<item android:color="#color/btnLinkTextColor" />
</selector>
In my case i replaced android:tint with app:tint and added to root element xmlns:app="http://schemas.android.com/apk/res-auto". It fixed crashing issue on API level < 21.
And color state selector /res/color/color_selector.xml looks like:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#151515"/>
<item android:state_focused="true" android:color="#151515"/>
<item android:color="#424242"/>
</selector>
It looks like AppCompat drawable tinting only works for action bar and "some widgets" on < API 21, but works for all drawables on API 21+.
When you set these attributes, AppCompat automatically propagates their values to the framework attributes on API 21+. This automatically colors the status bar and Overview (Recents) task entry.
On older platforms, AppCompat emulates the color theming where possible. At the moment this is limited to coloring the action bar and some widgets.
Source: https://android-developers.googleblog.com/2014/10/appcompat-v21-material-design-for-pre.html
The answer here also has more detail: https://stackoverflow.com/a/29155611/608312
item name="android:tint" is wrong.
fix the 'android:tint' to 'tint'
<style name="IconButton.Primary">
<item name="tint">#color/link_button_color</item>
</style>

Android material design buttons - Pre lollipop

How do I implement the "raised button" and the "flat button" as described in google's material design guidelines?
Raised buttons add dimension to mostly flat layouts. They emphasize >
functions on busy or wide spaces.
Use flat buttons for toolbars and dialogs to avoid excessive layering.
Source: http://www.google.com/design/spec/components/buttons.html
This requires Android 5.0
Raised Button
Inherit your button style from Widget.Material.Button, and the standard elevation and raising action will automatically be applied.
<style name="Your.Button" parent="android:style/Widget.Material.Button">
<item name="android:background">#drawable/raised_button_background</item>
</style>
Then you need to create a raised_button_background.xml file with your button's background color inside a ripple tag:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="#color/button_color"/>
</ripple>
Flat Button
Edit: Instead of my previous advice for flat buttons, you should instead use follow the advice given by Stephen Kaiser below:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DONE"
style="?android:attr/borderlessButtonStyle"
/>
Edit: If you are using Support Library, you can achieve the same result on Pre-Lollipop devices by using style="?attr/borderlessButtonStyle". (notice the absence of android:) The above example then becomes
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DONE"
style="?attr/borderlessButtonStyle"
/>
In order to implement the flat buttons, you could just add style="?android:attr/borderlessButtonStyle".
Example:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DONE"
style="?android:attr/borderlessButtonStyle"
/>
Here's the reference for the attribute.
You can use MaterialDesignLibrary. It's third party library.
This is a library with components of Android L to you use in android 2.2
If you want use this library, you only have to download MaterialDesign project, import it into your workspace and add the project as a library in your android project settings.
I'm working on a material compatibility library. The button class is there and supports animated shadows and the touch ripple. Maybe you will find it useful. Here's the link.
I use this as a background for a button with AppCompat and it depicts a raised button (with ripples n all), hope it helps.
myRaisedButton.xml - inside the drawable folder:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/yourColor"/>
<corners android:radius="6dp"/>
</shape>
</item>
<item android:drawable="?android:selectableItemBackground"/>
</layer-list>
styles.xml:
<resources>
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="AppTheme.Base" parent="Theme.AppCompat">
</resources>
styles.xml (v21):
...
<style name="AppTheme" parent="AppTheme.Base">
layout.xml:
...
android:background="#drawable/myRaisedButton"
For a description of how to do this using the appcompat libray, check my answer to another question: https://stackoverflow.com/a/27696134/1932522
This will show how to make use of the raised and flat buttons for both Android 5.0 and earlier (up to API level 11)!
You asked for material design buttons Library - you got it - https://github.com/navasmdc/MaterialDesignLibrary
You may also need to add a bottom margin to your button, in order to be able to see the raised-button shadow effect:
<item name="android:layout_marginBottom">#dimen/activity_vertical_margin</item>
<item name="android:elevation">1dp</item>

Cannot change android Switch style when using Holo Everywhere

I am having trouble changing the style of a Switch view in my project and can't figure out what I am doing wrong or missing... My project uses holo everywhere.
I can't change the text, the thumb or the track. I've tried applying android:thumb and android:track drawables directly from the xml but nothing changes. Not even the android:textOff and android:textOn have any effect.
I found a great post on how to customise the android Switch view style and looked through all the code but couldn't find anything I was doing wrong:
http://custom-android-dn.blogspot.co.uk/2013/01/how-to-use-and-custom-switch-in-android.html
Really not sure what else to try.
Here is the xml code:
<Switch
android:id="#+id/home_availability_switch"
style="#style/MySwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:enabled="true"
android:focusable="true"
android:textOff="Free"
android:textOn="Busy" />
Here is the style:
<style name="MySwitch" parent="#style/Holo.Switch.Light">
<item name="android:thumb">#drawable/selector_availability_switch_thumb</item>
<item name="android:track">#drawable/selector_availability_switch_background</item>
</style>
Here is the thumb selector
(these are default system drawables. i have tried with different drawables):
<item android:drawable="#drawable/switch_thumb_pressed_holo_light" android:state_pressed="true"/>
<item android:drawable="#drawable/switch_thumb_activated_holo_light" android:state_checked="true"/>
<item android:drawable="#drawable/switch_thumb_disabled_holo_light" android:state_enabled="false"/>
<item android:drawable="#drawable/switch_thumb_holo_dark"/>
Here is the track selector
(these are default system drawables. i have tried with different drawables):
<item android:drawable="#drawable/switch_bg_disabled_holo_dark" android:state_enabled="false"/>
<item android:drawable="#drawable/switch_bg_focused_holo_dark" android:state_focused="true"/>
<item android:drawable="#drawable/switch_bg_holo_dark"/>
I also found this post How can I style an Android Switch? and follow the instructions but had no luck.
Any one else had a similar experience when using Holo Everywhere?
You need to define the switch like this. Need the whole package name in there for it to work.
<org.holoeverywhere.widget.Switch
android:id="#+id/lockSwitch"
style="?switchStyleOld"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestSwitch" />
Hope this helps.

Default selector background in Clickable Views

I have some clickable views and I want to set the default available background that is present on list click (in ICS is a blue color). I have tried putting as background this:
android:background="#android:drawable/list_selector_background"
but it is not the default blue I have by default (the one I used is orange). What is the drawable used by default on android as click selector?
Thanks
This works for me:
android:background="?android:attr/selectableItemBackground"
It's list_selector_holo_dark or the equivalent holo light version; and these are the defaults in Honeycomb and above. list_selector_background is the non-holo version, used in Gingerbread and below.
EDIT: I believe (but can't confirm) that the platform agnostic selector is ?android:attr/listSelector
If you are using appcompat-v7, you can just use ?attr/selectableItemBackground.
There is a way to combine all the valid answers:
Define a attribute (eg. in values/attrs.xml):
<attr name="clickableItemBackground" format="reference"/>
In your platform dependent theme section (eg. in values/styles.xml or values/themes.xml) declare this:
<style name="Theme.Platform" parent="#android:style/Theme.Whatever">
<item name="clickableItemBackground">#android:drawable/list_selector_background</item>
</style>
In your platform dependent theme section for api-11+ (eg. in values-v11/styles.xml or values-v11/themes.xml) declare this:
<style name="Theme.Platform" parent="#android:style/Theme.Holo.Whatever">
<item name="clickableItemBackground">?android:attr/selectableItemBackground</item>
</style>
Then use ?attr/clickableItemBackground wherever needed.
A solution similar to flx's answer, but without additional attribute definition.
Platform independent style used for pre-Holo devices (in res\values\styles.xml):
<style name="SelectableItem">
<item name="android:background">#android:drawable/list_selector_background</item>
</style>
Style for Holo devices (API Level 14+) (in res\values-v14\styles.xml):
<style name="SelectableItem">
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
Apply style to needed view, e.g., LinearLayout:
<LinearLayout
style="#style/SelectableItem"
android:layout_width="match_parent"
android:layout_height="wrap_content">
...
</LinearLayout>
This works fine on api 11 and above. But as noted it wont work on previous versions.
android:background="?android:attr/selectableItemBackground"
Here is a solution to have it run on all versions running android.
Add the appropriate colors within the colors.xml which is located within your values folder. It should appear as such:
<color name="white">#ffffff</color>
<color name="blue">#7ecce8</color>
Create an xml selector file. Here I named it button_selection.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="#color/blue"/> <!--pressed -->
<item android:state_focused="true" android:drawable="#color/blue"/> <!-- focused -->
<item android:drawable="#color/white"/> <!-- default -->
</selector>
Go to your view or button and set the newly created button_selection.xml as its background.
android:background="#drawable/button_selection"
Alternatively,
android:background="?android:attr/listChoiceBackgroundIndicator
if you just want the items to highlight blue (or whatever the current default is) while they are clicked.
Setting Background restricts you from choosing a background color or drawable later!
So my advice is to add this style to your styles.xml:
<style name="TouchableView">
<item name="android:foreground">?android:attr/selectableItemBackground</item>
</style>
And then on every view you only need to add:
android:theme="#style/TouchableView"
Like ANY VIEW!
<TextView
android:id="#+id/my_orders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:theme="#style/TouchableView"
android:background="#color/white"
android:gravity="left"
android:padding="10dp"
android:text="#string/my_orders"
android:textColor="#color/gray"
android:textSize="14sp" />
Don't forget to add onClickListener to see the results.
In short - android:background="?selectableItemBackground" ;)

Categories

Resources