I saw new appCompat controls are available here. And implemented it in android app, but I don't find any specific way of customizing its color.
Just like if we set accent color in style, the edit text automatically catches it. But it is not working in case of AppCompatButton.
Does anybody find something regarding this?
See here: Coloring Buttons in Android with Material Design and AppCompat
To summarize, you can use the tintBackground attribute on the button itself or you can use colorControlNormal (or a combination).
Also, you can just use Button and it'll get converted to an AppCompatButton as long as you're using the theme and inheriting from AppCompatActivity correctly.
Examples from the linked URL
theme.xml:
<item name="colorButtonNormal">#color/button_color</item>
v21/theme.xml
<item name="android:colorButtonNormal">#color/button_color</item>
or
<Button
android:id="#+id/add_remove_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/bg_remove_btn_default"
android:textColor="#android:color/white"
tools:text="Remove" />
Use the SupportLib with AppCompatButton like this:
<android.support.v7.widget.AppCompatButton
android:id="#+id/add_remove_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#color/bg_remove_btn_default"
android:textColor="#android:color/white"
tools:text="Remove" />
app is a mxlns: xmlns:app="http://schemas.android.com/apk/res-auto"
so the backgroundTint works also for preLollipop
Related
I am creating an Android app and I wanted to use extended floating action button so I added this code to my activity:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/new_game_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|center"
android:text="#string/main_new_game"
android:backgroundTint="#color/colorAccent"
app:icon="#drawable/ic_play_arrow_24px"/>
The button looks exactly how it is supposed to, except that it does not have ripple effect on click.
How can I add the ripple effect? I took the code straight from https://material.io/develop/android/components/floating-action-button/#extended-fabs and it looks like the ripple should be there by default, but it does not work in my app. I have tried to create new project where I only set up the Material Components (https://material.io/develop/android/docs/getting-started/) and the button still does not have ripple effect. So it does not seem to be a problem with my project setup.
I have also tried setting the app:rippleColor attribute, setting android:clickable="true" android:focusable="true" to no avail. Only thing that sort of worked was setting android:foreground="?attr/selectableItemBackground", but the ripple effect was masked to rectangle instead of the shape of the extended FAB. Also setting the foreground is not very good approach since it is only supported on API 23 and higher and I am targeting API 21.
You are supposed to use this attribute app:rippleColor
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/new_game_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|center"
android:text="#string/main_new_game"
android:backgroundTint="#color/colorAccent"
app:icon="#drawable/ic_play_arrow_24px"
app:rippleColor="#color/colorPrimary" />
The default style of the ExtendedFloatingActionButton has a default rippleColor selector based on the colorOnSecondary.
Check in your app theme this color.
In any case you can override the color using:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
app:rippleColor="#color/my_selector" />
Or you can override the colorOnSecondary in your ExtendedFloatingActionButton using:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:theme="style/ExFabOverlay" />
with:
<style name="ExFabOverlay">
<item name="colorOnSecondary">#color/my_color</item>
</style>
Final note: use app:backgroundTint instead of android:backgroundTint.
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"
I'm using the new material components com.google.android.material:material with android x but I can't set a custom background to the button.
I know that I can use app:backgroundTint to change the color
but the default background has some padding that I want to get rid of, and the old way of using android:background to set my own background but this is no longer working.
I looked at the docs but can't find any mention to this change.
In the Material Components Library, the MaterialButton has a default style with insetBottom and insetTop with a value of 6dp.
You can change it using:
<com.google.android.material.button.MaterialButton
android:insetTop="0dp"
android:insetBottom="0dp"
../>
If you want to change the background color you can use the app:backgroundTint attribute or you can override some theme attributes from a default style then you can use new materialThemeOverlay attribute.
In your case you can do something like:
<style name="MtButtonStyle"
parent="Widget.MaterialComponents.Button">
<item name=“materialThemeOverlay”>#style/GreenButtonThemeOverlay</item>
</style>
<style name="GreenButtonThemeOverlay">
<item name="colorPrimary">#color/green</item>
</style>
Finally starting with the version 1.2.0-alpha06 you can use the android:background attribute in the MaterialButton.
<MaterialButton
app:backgroundTint="#null"
android:background="#drawable/button_drawable"
... />
The documentation for the MaterialButton class says:
Do not use the android:background attribute. MaterialButton manages its own background drawable, and setting a new background means MaterialButton can no longer guarantee that the new attributes it introduces will function properly. If the default background is changed, MaterialButton cannot guarantee well-defined behavior.
However, the GitHub readme says:
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.
This mentions only left/right inset, but the Attributes section of the readme shows that all four insets are supported:
So you could add these attributes to your <MaterialButton> tag:
android:insetTop="0dp"
android:insetBottom="0dp"
Looking at https://medium.com/#velmm/material-button-in-android-e4391a243b17 I found that app:backgroundTint (and app:backgroundTintMode) works. It changes a color, but not a drawable selector.
Also you can replace <Button with <android.widget.Button.
If you want to use gradient drawable as MaterialButton's background,
set Your MaterialButton as below:
<com.google.android.material.button.MaterialButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:backgroundTint="#null"
android:background="#drawable/group_47"
app:layout_constraintEnd_toEndOf="#+id/input_password"
app:layout_constraintStart_toStartOf="#+id/input_password"
app:layout_constraintTop_toBottomOf="#+id/input_password" />
If you wish to keep your
android:background="#drawable/button_background"
And have MaterialButton respect it, then you must set
app:backgroundTint="#null"
app:backgroundTintMode="add" // it doesn't matter the value, but it must be set
Please note that you can also use app:background instead, although I've noticed enough breaking changes that I still prefer the method above.
I face the same issue when I use state drawable in a Button but It does not change the background of the button. After searching for a long time, I found 2 solutions as below:
The first solution is change the application theme from MaterialComponents to AppCompat in values/themes.xml file. then state drawable will work well.
to
<style name="Theme.MyApplication" parent="Theme.AppCompat.DayNight.DarkActionBar">
If you still want to use MaterialComponents theme then you can try the second solution.Use <android.widget.Button instead of <Button or <com.google.android.material.button.MaterialButton
<android.widget.Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/state_test"
android:text="Button" />
The second solution I found at Here
The main reason for this decision by the google design team to exclude the functionality android:background="#drawable/" from the initial release versions of the material library is to enable developers to build consistent and professional-looking designs for apps at a faster pace. This is because most developers like me are bad in making decisions related to design and colors of the app.
Also, I found this snippet from google tutorial while migrating to MDC.
Just by using android:backgroundTint
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="android:backgroundTint">#color/pink</item>
</style>
<com.google.android.material.button.MaterialButton
android:id="#+id/followButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/channel_header_item_margin"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/titeChannelTV"
style="#style/MyButtonStyle"/>
using a simple
app:backgroundTint="#null"
with button attributes works perfectly.
I need to know what is the best (and recommented) way to tint a Material Button (AppCompatButton) using the latest AppCompat (23.2.1 for the time being). I could have never imagined that it would be so frustrating! I tried most of the answers from here but either they wouldn't work or worked with unexpected results.
I need to keep backwards compatibility to api >= 9 And just need the ripple effect to be applied to >=21 nothing fancy. So what is the best way so far?
I'd appreciate if you could provide both xml and java code.
There are many ways to do that.
My favorite is the following:
<Button
android:id="#+id/activity_main_some_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/Widget.AppCompat.Button.Colored"
android:text="This is a button" />
This automatically tints the button with the accent color you (hopefully) set in your theme, while maintaining pressed states at API < Lollipop and Ripple >= Lollipop.
If nothing else works you could just tint the button yourself:
AppCompatButton myExampleButton = new AppCompatButton(getContext());
myExampleButton.setSupportBackgroundTintList(ContextCompat.getColorStateList(getContext(),
R.color.some_color));
Update
You can do the following to use a self defined color:
<style name="MyButtonTheme" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">#color/someColor</item>
</style>
Define a new style with the desired color.
<Button
android:id="#+id/activity_main_some_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/MyButtonTheme"
android:text="This is a button" />
Set it to your button.
How to create an ImageButton without border (just the image should be visible)? One could achieve this by setting imageButton.setBackgroundDrawable(null), but this also removes the focus and selection colors.
The goal is that initially only the image without borders is visible. But when the user focuses/touches/clicks the image this should be indicated by hightlighting the image like regular buttons.
Solution in Java-Code for API 14 is preferred. Thank you!
As has been mentioned, the borderlessButtonStyle built into the default themes on API11 and above is the simplest way to achieve this effect. You mentioned you are creating your buttons in Java code instead of XML, so there are two options depending on how you need to apply the style.
Option #1: Add it to the theme
If all the Button or ImageButton instances in your application (or at least within the Activity) need to have this style applied, add the styling to your theme instead:
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light">
<!-- Default style for ImageButtons -->
<item name="android:imageButtonStyle">?android:borderlessButtonStyle</item>
<!-- Default style for Buttons -->
<item name="android:buttonStyle">?android:borderlessButtonStyle</item>
</style>
</resources>
With this theme applied to your Application or Activity, you won't have to declare the style of each element, you can just declare them as
Button button = new Button(context);
ImageButton imageButton = new ImageButton(context);
And the styling will be pulled from the theme.
Option #2: Declare it in the constructor
If only a couple buttons need to be styled this way, you can pass the style attribute you want to apply directly to each view, like so:
Button button = new Button(context, null, android.R.attr.borderlessButtonStyle);
ImageButton imageButton = new ImageButton(context, null, android.R.attr.borderlessButtonStyle);
This version supplies a different default style attribute for the widget to use.
Use borderlessButtonStyle to ImageButton
<ImageButton
style="?android:borderlessButtonStyle"
android:layout_width="58dp"
android:layout_height="wrap_content"
android:contentDescription="Delete"
android:src="#android:drawable/ic_delete" />
Ref : Google I/O 2013 - Android Design for UI Developers
Use a selector for the background like this:
/res/drawable/my_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/my_drawable" />
<item android:drawable="#android:color/transparent" />
</selector>
my_drawable is whatever drawable you want as your border.
Then your ImageButton
<ImageButton
android:layout_height="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/my_selector"
android:src="#drawable/your_bitmap" />
your_bitmap is your actual image.
Your answer is here in the Nick Butcher and Roman Nurik talk for Google I/O 2013 about android design for UI developers.
Min: 31:40:
https://www.youtube.com/watch?v=Jl3-lzlzOJI#t=31m40s
The only problem with this approach is that style="?android:borderlessButtonStyle" is available for API 11 and above so if you want the same behaviour on any API before the 11, then you will have to stick with selectors.
By the way I highly recommend you to watch the whole talk because it is really interesting.
You have to add
imageButton.setClickable(true);
imageButton.setFocusable(true);
And it will works...
That's the way in your xml file :
android:clickable="true"
android:focusable="true"
Hope this help
I hope this will help you. please give the background as transparent
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/facebookbuttonanimation"
android:background="#00000000"
/>
You can design different images for clicked/not clicked states and set them in the onTouchListener as shown in the selected answer for this SO post.
Then you can set the image back to the previous image on post longclick or click.