Android material design buttons - Pre lollipop - android

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>

Related

Android Background Drawable Not Working in Button Since Android Studio 4.1

I find out that since Android Studio 4.1 I cannot change the background color of a Button by setting color on its android:background, just no effect. And custom Drawable is not working as well.
My background Drawable:
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1.5dp"
android:color="#android:color/black" />
<solid
android:color="#android:color/white" />
<corners
android:radius="8dp" />
</shape>
My Button:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add To Cart"
android:background="#drawable/background3"/>
Result:
The Android Studio 4.1 new-project wizard, for many of its templates, has the project use the Material Components for Android library. And, it sets up the default theme to be based on Theme.MaterialComponents.DayNight.DarkActionBar.
A side effect of this is that any <Button> elements in a layout get turned into MaterialButton widgets, not regular Button widgets. MaterialButton ignores android:background.
If all you want to do is to change the color, use android:backgroundTint or change the colorPrimary attribute in the theme.
If you want a button that has a custom background, and your theme is set up to use Theme.MaterialComponents, you could switch the XML element in the layout to be <android.widget.Button> instead of <Button>. This should cause the Material Components for Android to ignore that element, and you can manipulate this button normally with respect to XML attributes.
UPDATE 03/2021
app:backgroundTint="#null" //just need this
android:background="#drawable/background_button"
Ok, since MaterialButton is the default Button starting from Android Studio 4.1, we can modify the shape by using app:shapeAppearanceOverlay attribute.
1. Create a Custom Style in themes.xml:
<style name="leaf">
<item name="cornerSizeTopLeft">70%</item> //can specify corner position
<!--<item name="cornerFamilyTopLeft">cut</item>-->
<item name="cornerSizeBottomRight">70%</item>
<!--<item name="cornerFamilyBottomRight">cut</item>-->
</style>
2. Apply Style in Material Button:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Show"
app:shapeAppearanceOverlay="#style/leaf" /> //here
Result:
Helpful video:
https://www.youtube.com/watch?v=jihLJ0oVmGo
Add only this:
app:backgroundTint="#null"
I found easiest solution in this video.
https://www.youtube.com/watch?v=E_1H52FEqII
Just go to themes.xml under values folder in project window and change the MaterialComponents to AppCompact in both themes and button start working as normal as it was in past.
Existing: Theme.MaterialComponents.DayNight.DarkActionBar
After Modification: Theme.AppCompat.DayNight.DarkActionBar
It worked for me, hope it works for others as weell.
Just set null to backgroundTint.
android:backgroundTint="#null".

What is alternative of android:background in MaterialComponents?

Question: android:background is not giving effect in MaterialComponents.
In my project, I was using AppCompat
( <style name="DayTheme" parent="Theme.AppCompat.Light.NoActionBar">)
and everything was working fine.
but, because of some requirement in my project, now, I've to use MaterialComponents
( <style name="DayTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> )
And because of that some UI looks bad.
Problem: In AppComapt, I was using android:background="#drawable/bg_circle_btn" which was working fine, but in MaterialComponents, this background is not giving effect.
I tried to change color, shape n all but it's not giving effect.
<Button
android:id="#+id/custom_category_image"
android:layout_width="match_parent"
android:layout_height="25dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#drawable/bg_circle_btn"
android:text="A"
android:textColor="#color/colorWhite"
android:textSize="12dp"
android:visibility="gone"
app:srcCompat="#drawable/ic_navigate_next_black_24dp" />
(I'm using button, because, instead of any fixed image, I'm setting the first letter of title in this button and this button is actually inside carview, so it'll be cirlce also.)
bg_circle_btn:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="?attr/toolbarcolor" />
<size
android:width="120dp"
android:height="120dp" />
</shape>
Please note that, in whole project, I need to use this background, so please do not give any other alternative ways.
You could use androidx.appcompat.widget.AppCompatButton instead of Button. This will solve your problem.
Besides this you can use android:backgroundTint to change the color only.
To change both (Shape&Color) for com.google.android.material.button.MaterialButton, you have to do this from you code:
setBackgroundResource(R.drawable.bg_circle_btn) setBackgroundTintList(ColorStateList.valueOf(Color.RED))
Since you are using the Material Components theme, <Button> is replaced by the <com.google.android.material.button.MaterialButton> at runtime. There is an auto-inflation (check this post).
To change the background color just use the app:backgroundTint attribute.
It works with a color, not a drawable.
Something like:
<com.google.android.material.button.MaterialButton
app:backgroundTint="#color/...."
../>
If you want to apply a custom background to the MaterialButton:
you can use
android:background in MaterialButton but it requires at least the version 1.2.0-alpha06 (check this answer)
use an AppCompatButton as suggested by #Md. Asaduzzaman
You cannot use background attribute, when using MaterialComponents theme.
You can only change its color using backgroundTint attribute.
Possible way of achieving your task is to use View/Layout, then providing a shape background on it.
For example using CardView, you can do this as follow.
You cannot use background on CardView, but using some of the CardView useful attributes you can achieve your task:
<androidx.cardview.widget.CardView
android:layout_width="120dp"
android:layout_height="120dp"
app:cardBackgroundColor="#color/colorPrimary"
app:cardCornerRadius="65dp">
<Widget_You_Want />
</androidx.cardview.widget.CardView>
For a round circle you could use shape theming with Material Components. You would probably want to define a ShapeAppearance like
<style name="ShapeAppearance.Round" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
Then apply that to your button (or button style) with app:shapeAppearance="#style/ShapeAppearance.Round"

After migration to AndroidX android:button is not respected for API below Lollipop

I have very simple checkbox:
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/clipboardBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/clipboard_checkbox" />
For checked/unchecked I have two different images.
After migration to AndroidX I see default image for Android on devices below API 21.
What I've tried already:
change CheckBox to AppCompatCheckbox (from AndroidX) - nothing changed
set background to checkbox & set android:button="#null" - background is OK, but I still see default image on background (see image below)
Seems that Android completly disrespect button attribute.
I am out of ideas. For Lollipop+ everythink works as it should. Have anyone faced issue like this?
Only change I did was migration to AndroidX :/
In the appcompat theme, the checkBoxStyle below API 21 is defined as
<style name="Base.Widget.AppCompat.CompoundButton.CheckBox" parent="android:Widget.CompoundButton.CheckBox">
<item name="android:button">?android:attr/listChoiceIndicatorMultiple</item>
<item name="buttonCompat">?attr/listChoiceIndicatorMultipleAnimated</item>
<item name="android:background">?attr/controlBackground</item>
</style>
the attr buttonCompat has a default value to show the click animation. The attr buttonCompat take effect and ignore the button attr.
To fix it, the attr buttonCompat must be undefined. In your theme add
<item name="checkboxStyle">#style/MyCheckBox</item>
and add a style
<style name="MyCheckBox" parent="android:Widget.CompoundButton.CheckBox">
<item name="android:button">?android:attr/listChoiceIndicatorMultiple</item>
<item name="buttonCompat">#null</item>
<item name="android:background">?attr/selectableItemBackgroundBorderless</item>
</style>
Also in your values-v21 dir, add this to your theme
<item name="checkboxStyle">?android:attr/checkboxStyle</item>
Change CheckBox to AppCompatCheckBox(AndroidX) and replace android:button to app:buttonCompat
<androidx.appcompat.widget.AppCompatCheckBox
android:id="#+id/clipboardBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/email_sign_in_button"
app:buttonCompat="#drawable/clipboard_checkbox" />
You need to set the button and buttonCompat null for androidx libraries. It will look like below-
<androidx.appcompat.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#null"
app:buttonCompat="#null"
android:background="#drawable/cb_pause_resume_selector"
/>

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

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.

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