I created a button and I want to add ripple effect to that button!
I created a button bg XML file: (bg_btn.xml)
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFF" android:endColor="#00FF00" android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>
And this is my ripple effect file: (ripple_bg.xml)
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f816a463"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f816a463" />
</shape>
</item>
</ripple>
And This is my Button which I want to add ripple effect:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp"
android:textColor="#fff"
android:background="#drawable/ripple_bg"
android:clickable="true" />
But after adding ripple effect button background is transparent, and button display only when clicked,
like this:
Before Click
On Click
But I need both button background color and ripple effect,
I found some of this code in different blogs of Stack Overflow, but still it is not working!
Here is another drawable xml for those who want to add all together gradient background, corner radius and ripple effect:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorPrimaryDark">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimaryDark" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
<item android:id="#android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#color/colorPrimaryLight"
android:startColor="#color/colorPrimary"
android:type="linear" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
</ripple>
Add this to the background of your button.
<Button
...
android:background="#drawable/button_background" />
PS: this answer works for android api 21 and above.
Add the "?attr/selectableItemBackground" to your view's android:foreground attribute if it already has a background along with android:clickable="true".
Add Ripple Effect/Animation to a Android Button
Just replace your button background attribute with android:background="?attr/selectableItemBackground" and your code looks like this.
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:text="New Button" />
Another Way to Add Ripple Effect/Animation to an Android Button
Using this method, you can customize ripple effect color. First, you have to create a xml file in your drawable resource directory. Create a ripple_effect.xml file and add following code.
res/drawable/ripple_effect.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f816a463"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f816a463" />
</shape>
</item>
</ripple>
And set background of button to above drawable resource file
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ripple_effect"
android:padding="16dp"
android:text="New Button" />
In addition to Jigar Patel's solution, add this to the ripple.xml to avoid transparent background of buttons.
<item
android:id="#android:id/background"
android:drawable="#color/your-color" />
Complete xml :
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#color/your-color"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/your-color" />
</shape>
</item>
<item
android:id="#android:id/background"
android:drawable="#color/your-color" />
</ripple>
Use this ripple.xml as background in your button :
android:background="#drawable/ripple"
When the button has a background from the drawable, we can add ripple effect to the foreground parameter.. Check below code its working for my button with a different background
<Button
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center"
android:layout_centerHorizontal="true"
android:background="#drawable/shape_login_button"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:text="#string/action_button_login"
/>
Add below parameter for the ripple effect
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
For reference refer below link
https://jascode.wordpress.com/2017/11/11/how-to-add-ripple-effect-to-an-android-app/
AppCompat v7+
If you don't prefix with ?android: your app will crash.
You should use "?android:attr/selectableItemBackground" or "?android:attr/selectableItemBackgroundBorderless", based on your preference. I prefer Borderless.
You can put it either in android:background or android:foreground to keep existing properties.
The element must have android:clickable="true" and android:focusable="true" in order for this to work, but many elements, such as buttons, have them true by default.
<Button
...
android:background="#color/white"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
/>
<TextView
...
android:background="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
/>
Programmatically (Java)
TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
myView.setBackgroundResource(value.resourceId);
myView.setFocusable(true); // If needed for view type
Programmatically (Kotlin)
val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
myView.setBackgroundResource(value.resourceId)
myView.setFocusable(true) // If needed for view type
Reusable Kotlin Extension Function
myView.ripple()
fun View.ripple(): View {
val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
setBackgroundResource(value.resourceId)
isFocusable = true // Required for some view types
return this
}
Adding foreground and clickable attributes worked for me.
<Button
...
android:background="#color/your_color"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true" />
A simple approach is to set a view theme as outlined here.
some_view.xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:src="#drawable/up_arrow"
android:theme="#style/SomeButtonTheme"/>
some_style.xml
<style name="SomeButtonTheme" >
<item name="colorControlHighlight">#color/someColor</item>
</style>
In addition to Sudheesh R
Add Ripple Effect/Animation to a Android Button with button rectangle shape with corner
Create xml file res/drawable/your_file_name.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#color/colorWhite"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimaryDark" />
<corners android:radius="50dp" />
</shape>
</item>
<item android:id="#android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#color/colorAccent"
android:startColor="#color/colorPrimary"
android:type="linear" />
<corners android:radius="50dp" />
</shape>
</item>
</ripple>
try this
<Button
android:id="#+id/btn_location"
android:layout_width="121dp"
android:layout_height="38dp"
android:layout_gravity="center"
android:layout_marginBottom="24dp"
android:layout_marginTop="24dp"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:background="#drawable/btn_corner"
android:gravity="center_vertical|center_horizontal"
android:paddingLeft="13dp"
android:paddingRight="13dp"
android:text="Save"
android:textColor="#color/color_white" />
Just use :
android:backgroundTint="#f816a463"
Instead of:
android:background="#f816a463"
Don't forget to change your Button to android.support.v7.widget.AppCompatButton
An alternative solution to using the <ripple> tag (which I personally prefer not to do, because the colors are not "default"), is the following:
Create a drawable for the button background, and include <item android:drawable="?attr/selectableItemBackground"> in the <layer-list>
Then (and I think this is the important part) programmatically set backgroundResource(R.drawable.custom_button) on your button instance.
Activity/Fragment
Button btn_temp = view.findViewById(R.id.btn_temp);
btn_temp.setBackgroundResource(R.drawable.custom_button);
Layout
<Button
android:id="#+id/btn_temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_button"
android:text="Test" />
custom_button.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
<corners android:radius="10dp" />
</shape>
</item>
<item android:drawable="?attr/selectableItemBackground" />
</layer-list>
setForeground is added in API level 23. Leverage the power of RevealAnimator in case u need to relay on foreground property !
<View
android:id="#+id/circular_reveal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/primaryMilk_22"
android:elevation="#dimen/margin_20"
android:visibility="invisible" />
With kotlin ext function, it's way osm !
fun View.circularReveal() {
val cx: Int = width / 2
val cy: Int = height / 2
val finalRadius: Int =
width.coerceAtLeast(height)
val anim: Animator = ViewAnimationUtils.createCircularReveal(
this,
cx,
cy,
0f,
finalRadius.toFloat()
)
anim.interpolator = AccelerateDecelerateInterpolator()
anim.duration = 400
isVisible = true
anim.start()
anim.doOnEnd {
isVisible = false
}
}
Related
I am trying to have two text views inside a Linear Layout with a horizontal orientation. Now I want to have the following things for each text view:
An icon at left - implemented using android:drawableLeft="#drawable/ic_lightbulb_outline_blue_24dp"
A round border around the text view - implemented using android:background="#drawable/round_border"
Also, need that ripple effect on touching a touch item
The 3rd point is implemented in other text views using the att.
android:background="?selectableItemBackground"
android:clickable="true"
But there is already a background att. for the round border. Now my question is how to achieve that ripple effect? Is using following att. only way:
android:foreground="?selectableItemBackground"
Android shows this att. is not supported in lower api versions so worried.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="#string/vision_mission"
android:gravity="center"
android:layout_margin="8dp"
android:padding="8dp"
android:textSize="16sp"
android:onClick="openVisionMission"
android:drawableLeft="#drawable/ic_lightbulb_outline_blue_24dp"
android:background="#drawable/round_border"
android:clickable="true"
android:focusable="true"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="#string/team"
android:textSize="16sp"
android:drawableLeft="#drawable/ic_people_blue_24dp"
android:background="#drawable/round_border"
android:clickable="true"
android:focusable="true"
android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_marginRight="8dp"
android:gravity="center"/>
</LinearLayout>
You can achieve ripple effect and text view rounded background at the same time using the following code.
Custom ripple drawable, it require API level 21+
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/grey">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="#android:color/holo_blue_dark" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="#android:color/holo_blue_dark" />
</shape>
</item>
</ripple>
After that set background of your text view
android:background="#drawable/custom_ripple"
For pre lollypop ie. below API level 21
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="#color/colorDarkGray"/>
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="#color/colorButtonGreen"/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#color/colorButtonGreenFocused"/>
</shape>
</item>
</selector>
It is not exactly what you are looking for.
You can achieve easily something similar with a MaterialButton with a OutlinedButton style.
Something like:
<com.google.android.material.button.MaterialButton
style="#style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
app:icon="#drawable/ic_add_24px"
android:text="...."
.../>
You can customize the padding between the icon and the text, the textColor, the strokeWidth, the strokeColor and also the color selector used for the app:rippleColor
<com.google.android.material.button.MaterialButton
style="#style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
app:icon="#drawable/ic_add_24px"
app:strokeColor="#color/primaryDarkColor"
app:strokeWidth="2dp"
app:iconPadding="16dp"
.../>
you can change your background drawable with selector tag
<?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/button_pressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/button_focused" /> <!-- focused -->
<item android:state_hovered="true"
android:drawable="#drawable/button_focused" /> <!-- hovered -->
<item android:drawable="#drawable/button_normal" /> <!-- default -->
</selector>
I created a button and I want to add ripple effect to that button!
I created a button bg XML file: (bg_btn.xml)
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFF" android:endColor="#00FF00" android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>
And this is my ripple effect file: (ripple_bg.xml)
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f816a463"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f816a463" />
</shape>
</item>
</ripple>
And This is my Button which I want to add ripple effect:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp"
android:textColor="#fff"
android:background="#drawable/ripple_bg"
android:clickable="true" />
But after adding ripple effect button background is transparent, and button display only when clicked,
like this:
Before Click
On Click
But I need both button background color and ripple effect,
I found some of this code in different blogs of Stack Overflow, but still it is not working!
Here is another drawable xml for those who want to add all together gradient background, corner radius and ripple effect:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorPrimaryDark">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimaryDark" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
<item android:id="#android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#color/colorPrimaryLight"
android:startColor="#color/colorPrimary"
android:type="linear" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
</ripple>
Add this to the background of your button.
<Button
...
android:background="#drawable/button_background" />
PS: this answer works for android api 21 and above.
Add the "?attr/selectableItemBackground" to your view's android:foreground attribute if it already has a background along with android:clickable="true".
Add Ripple Effect/Animation to a Android Button
Just replace your button background attribute with android:background="?attr/selectableItemBackground" and your code looks like this.
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:text="New Button" />
Another Way to Add Ripple Effect/Animation to an Android Button
Using this method, you can customize ripple effect color. First, you have to create a xml file in your drawable resource directory. Create a ripple_effect.xml file and add following code.
res/drawable/ripple_effect.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f816a463"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f816a463" />
</shape>
</item>
</ripple>
And set background of button to above drawable resource file
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ripple_effect"
android:padding="16dp"
android:text="New Button" />
In addition to Jigar Patel's solution, add this to the ripple.xml to avoid transparent background of buttons.
<item
android:id="#android:id/background"
android:drawable="#color/your-color" />
Complete xml :
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#color/your-color"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/your-color" />
</shape>
</item>
<item
android:id="#android:id/background"
android:drawable="#color/your-color" />
</ripple>
Use this ripple.xml as background in your button :
android:background="#drawable/ripple"
When the button has a background from the drawable, we can add ripple effect to the foreground parameter.. Check below code its working for my button with a different background
<Button
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center"
android:layout_centerHorizontal="true"
android:background="#drawable/shape_login_button"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:text="#string/action_button_login"
/>
Add below parameter for the ripple effect
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
For reference refer below link
https://jascode.wordpress.com/2017/11/11/how-to-add-ripple-effect-to-an-android-app/
AppCompat v7+
If you don't prefix with ?android: your app will crash.
You should use "?android:attr/selectableItemBackground" or "?android:attr/selectableItemBackgroundBorderless", based on your preference. I prefer Borderless.
You can put it either in android:background or android:foreground to keep existing properties.
The element must have android:clickable="true" and android:focusable="true" in order for this to work, but many elements, such as buttons, have them true by default.
<Button
...
android:background="#color/white"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
/>
<TextView
...
android:background="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
/>
Programmatically (Java)
TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
myView.setBackgroundResource(value.resourceId);
myView.setFocusable(true); // If needed for view type
Programmatically (Kotlin)
val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
myView.setBackgroundResource(value.resourceId)
myView.setFocusable(true) // If needed for view type
Reusable Kotlin Extension Function
myView.ripple()
fun View.ripple(): View {
val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
setBackgroundResource(value.resourceId)
isFocusable = true // Required for some view types
return this
}
Adding foreground and clickable attributes worked for me.
<Button
...
android:background="#color/your_color"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true" />
A simple approach is to set a view theme as outlined here.
some_view.xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:src="#drawable/up_arrow"
android:theme="#style/SomeButtonTheme"/>
some_style.xml
<style name="SomeButtonTheme" >
<item name="colorControlHighlight">#color/someColor</item>
</style>
In addition to Sudheesh R
Add Ripple Effect/Animation to a Android Button with button rectangle shape with corner
Create xml file res/drawable/your_file_name.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#color/colorWhite"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimaryDark" />
<corners android:radius="50dp" />
</shape>
</item>
<item android:id="#android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#color/colorAccent"
android:startColor="#color/colorPrimary"
android:type="linear" />
<corners android:radius="50dp" />
</shape>
</item>
</ripple>
try this
<Button
android:id="#+id/btn_location"
android:layout_width="121dp"
android:layout_height="38dp"
android:layout_gravity="center"
android:layout_marginBottom="24dp"
android:layout_marginTop="24dp"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:background="#drawable/btn_corner"
android:gravity="center_vertical|center_horizontal"
android:paddingLeft="13dp"
android:paddingRight="13dp"
android:text="Save"
android:textColor="#color/color_white" />
Just use :
android:backgroundTint="#f816a463"
Instead of:
android:background="#f816a463"
Don't forget to change your Button to android.support.v7.widget.AppCompatButton
An alternative solution to using the <ripple> tag (which I personally prefer not to do, because the colors are not "default"), is the following:
Create a drawable for the button background, and include <item android:drawable="?attr/selectableItemBackground"> in the <layer-list>
Then (and I think this is the important part) programmatically set backgroundResource(R.drawable.custom_button) on your button instance.
Activity/Fragment
Button btn_temp = view.findViewById(R.id.btn_temp);
btn_temp.setBackgroundResource(R.drawable.custom_button);
Layout
<Button
android:id="#+id/btn_temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_button"
android:text="Test" />
custom_button.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
<corners android:radius="10dp" />
</shape>
</item>
<item android:drawable="?attr/selectableItemBackground" />
</layer-list>
setForeground is added in API level 23. Leverage the power of RevealAnimator in case u need to relay on foreground property !
<View
android:id="#+id/circular_reveal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/primaryMilk_22"
android:elevation="#dimen/margin_20"
android:visibility="invisible" />
With kotlin ext function, it's way osm !
fun View.circularReveal() {
val cx: Int = width / 2
val cy: Int = height / 2
val finalRadius: Int =
width.coerceAtLeast(height)
val anim: Animator = ViewAnimationUtils.createCircularReveal(
this,
cx,
cy,
0f,
finalRadius.toFloat()
)
anim.interpolator = AccelerateDecelerateInterpolator()
anim.duration = 400
isVisible = true
anim.start()
anim.doOnEnd {
isVisible = false
}
}
I'm trying to add ripple effect to a custom button. But the only solution I found is adding a background which I have already done for achieving rounded corners for that button. Now I want to add the ripple effect. This is how my button tag looks so far:
<Button
android:text="PLAY"
android:id="#+id/button"
android:textSize="20dp"
android:layout_width="75dp"
android:layout_height="75dp"
android:background="#drawable/roundedbutton"
android:onClick="gotomainpage"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="200dp" />
use this code in your button
android:foreground="?attr/selectableItemBackground"
Easy
1. Creating an Ripple Drawable Contains the Backgound Shape
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?colorControlHighlight"> //defaul ripple color
<item>
<shape //the background shape when it's not being click
android:shape="rectangle">
<solid
android:color="#color/colorPrimary" />
<corners
android:radius="32dp" />
</shape>
</item>
</ripple>
2. Applying the Drawable to the Button and REMOVE THE SHADOW
<Button
style="?borderlessButtonStyle" //remove the default shadow
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="#drawable/background_button" //here
android:text="Sign up"
android:textAllCaps="false"
android:textColor="#android:color/white" />
Try adding a android:foreground="#drawable/ripple"
drawable/ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/ripple_white">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
if the View has a radius on its corners, apply this XML inside the shape (otherwise the ripple goes all the way to the corner);
<corners android:radius="10dp"/>
if you want ripples that end up as circles then use this
drawable/ripple_circle.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/ripple_white">
<item android:id="#android:id/mask">
<shape android:shape="oval">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
This method requires minimum API level 21 or later and android:foreground has no effect on API levels lower than 23
I'm following the tips from questions like this to create a button style like suggested on Material Design.
However, I need to change the corner radius and haven't been able to do so by inheriting Widget.AppCompat.Button.Colored style and setting the radius parameter.
How can I have the same style but with rounded corners?
With the Material Components Library:.
Add the dependency to your build.gradle:
dependencies { implementation ‘com.google.android.material:material:1.3.0’ }
In this case you can use a MaterialButton in your layout file:
<com.google.android.material.button.MaterialButton
....
style="#style/Widget.MaterialComponents.Button"
app:cornerRadius=".."
app:strokeColor="#color/colorPrimary"/>
Use app:cornerRadius attribute to change the size of corner radius. This will round off the corners with specified dimensions.
You can also customize the corners using the shapeAppearanceOverlay attribute.
<style name="MyButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="shapeAppearanceOverlay">#style/MyShapeAppearance</item>
</style>
<style name="MyShapeAppearance">
<item name="cornerFamily">rounded</item>
<item name="cornerFamilyTopRight">cut</item>
<item name="cornerFamilyBottomRight">cut</item>
<item name="cornerSizeTopLeft">32dp</item>
<item name="cornerSizeBottomLeft">32dp</item>
</style>
The official doc is here and all the android specs here.
With Jetpack Compose 1.0.x use the shape parameter:
Button( onClick = { /* Do something! */ },
shape = RoundedCornerShape(8.dp)) {
Text("Button")
}
Button(modifier = Modifier.padding(16.dp),
onClick = { /* Do something! */ },
shape = RoundedCornerShape(
50, // topEndPercent
0, // topEndPercent
0, // bottomEndPercent
50. // bottomStartPercent
)
) {
Text("Button")
}
OLD Support Library:
With the new Support Library 28.0.0, the Design Library now contains the Material Button.
You can add this button to our layout file with:
<android.support.design.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="XXXXX"
android:textSize="18sp"
android:backgroundTint="#color/colorPrimary"
app:icon="#drawable/ic_android_white_24dp" />
You can set the corner radius with this attribute:
app:cornerRadius: Used to define the radius used for the corners of the button
dependencies {
implementation 'com.android.support:design:28.0.0'
}
Update:
Answer by Gabriele Mariotti below is now better.
Old answer:
You need to inherit that style.
Add into your styles.xml:
<style name="AppTheme.RoundedCornerMaterialButton" parent="Widget.AppCompat.Button.Colored">
<item name="android:background">#drawable/rounded_shape</item>
</style>
Add file drawable/rounded_shape.xml:
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="#color/colorAccent" >
</solid>
<corners
android:radius="11dp" >
</corners>
</shape>
And finally in your layout:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test Text"
style="#style/AppTheme.RoundedCornerMaterialButton"/>
Edit: updated answer to use theme's color rather than hardcoded one.
Rounded Material Button with Ripple effect
Create a file in drawable folder ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimary" />
<corners android:radius="20dp" />
</shape>
</item>
<item android:drawable="#drawable/rounded_shape" />
</ripple>
Create a file in drawable folder rounded_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="#color/colorPrimary" >
</solid>
<corners
android:radius="20dp" >
</corners>
</shape>
And on your Button:
<Button
android:id="#+id/button1"
android:background="#drawable/ripple"
android:text="Login"/>
Now use MaterialButton for rounded button many more thing you can do with this. please follow link
and add app:cornerRadius="8dp"for rounded corner
and don't forget to add google material libs in build.gradle
implementation "com.google.android.material:material:1.1.0"
I will tell you my exact solution for this . Inside selector tags, you can put items (functionality of the buttons)
Second item of the selector tag has the opposite behaviour. You can add as much as selector (button behaviour)
ADD THIS DRAWABLE XML AS A BACKGROUND OF THE BUTTON android:background="#drawable/this xml"
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#ffffff"> <!-- this is the ripple color(first touch color changes into this color) -->
<item>
<selector>
<item android:state_enabled="true">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- default button color -->
<solid android:color="#color/colorPrimary"></solid>
<corners android:radius="151dp"></corners>
</shape>
</item>
<item> //first item was state enabled so this is automatically state disabled
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- button disabled color opposite behaviour -->
<solid android:color="#e9d204"></solid>
<corners android:radius="151dp"></corners>
</shape>
</item>
</selector>
</item>
<item>
<selector>
<item android:state_pressed="true">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- button first touch of your finger color -->
<solid android:color="#1989fa"></solid>
<corners android:radius="151dp"></corners>
</shape>
</item>
</selector>
</item>
<item>
<selector>
<item android:state_hovered="true">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- hovered with a note pencil -->
<solid android:color="#4affffff"></solid>
<corners android:radius="151dp"></corners>
</shape>
</item>
</selector>
</item>
</ripple>
Also another simple way is wrap it around cardView,Remember to set the layout_width and layout_height of the cardView to wrap_content, also all the needed margin the button will need should be applied to the cardView
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="40dp"
app:elevation="10dp">
<android.support.v7.widget.AppCompatButton
android:id="#+id/login_twitter"
android:tag="login_twitter"
android:layout_width="300dp"
android:layout_height="60dp"
android:paddingLeft="10dp"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:textColor="#color/blue_grey_ligthen_5"
android:drawableLeft="#drawable/twitter"
android:background="#color/twitter"
android:text="#string/login_with_twitter" />
</android.support.v7.widget.CardView>
If you don't want to change the theme for the whole app.You can use the material theme for this view specifically:
<com.google.android.material.button.MaterialButton
android:id="#+id/fooButon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:fontFamily="sans-serif"
android:padding="8dp"
==> android:theme="#style/Theme.MaterialComponents.Light"
app:backgroundTint="#color/base_white" />
Try below code Create a drawable file called circular_button.xml and insert the below
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#008577" />
<corners android:bottomRightRadius="100dp"
android:bottomLeftRadius="100dp"
android:topRightRadius="100dp"
android:topLeftRadius="100dp"/>
</shape>
Then change the background of the button to this drawable file
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/circle_button"
android:text="Button"/>
If you want a full circle button you can use the below drawable
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#008577"/>
<size
android:width="120dp"
android:height="120dp"/>
</shape>
To describe my problem i created small example.
I have linearlayout with imageview and textview. For linearlayout i've set ripple drawable as background. But when i click or long click on linearlayout ripple animation shows under imageview. How show animation over imageview ?
main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linear"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#drawable/ripple"
android:clickable="true"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:src="#mipmap/index" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is ripple test"
android:textColor="#FF00FF00" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
drawable-v21/ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#FFFF0000">
<item>
<shape android:shape="rectangle">
<solid android:color="#FF000000"/>
</shape>
</item>
</ripple>
drawable/ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FFFF0000" />
</shape>
</item>
<item android:state_focused="true">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FFFF0000" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FF000000" />
</shape>
</item>
</selector>
screenshot how it looks now:
Add the ripple like this
android:foreground="?android:attr/selectableItemBackground"
based on this answer https://stackoverflow.com/a/35753159/2736039
Add android:background="#null" for the ImageView
If your app needs to run on API < 23, you won't be able to use the foreground attribute on views other than FrameLayout, which means adding another [useless] level in the view tree hierarchy.
Another solution is to wrap your image with a <ripple>, set it as your ImageView's background, and use tint and tintMode to "hide" the src image so the background image that has the ripple over it is visible.
<!-- In your layout file -->
<ImageView
android:adjustViewBounds="true"
android:background="#drawable/image_with_ripple"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/image"
android:tint="#android:color/transparent"
android:tintMode="src_in" />
<!-- drawable/image_with_ripple.xml -->
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?colorControlHighlight">
<item android:drawable="#drawable/image" />
</ripple>
Not only this works on API 21+ but if your image has rounded corners – or is another type of non-rectangle shape, like a star or a heart icon – the ripple will remain in its bounds instead of filling the view's rectangle bounds, which gives a better look in some cases.
See this Medium article for an animated GIF to see how this technique compares to using a <FrameLayout> or the foreground attribute.
Resolve for API < 21
<ImageView
android:id="#+id/favorite_season"
style="?android:attr/borderlessButtonStyle"
android:background="?android:attr/selectableItemBackground"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_margin="22dp"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_star"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
Simple use these two lines as attribute in that ImageView.
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"