Android: selectableItemBackground not working on button with xml drawable - android

I made a rounded button with xml drawable and applied android:foreground="?attr/selectableItemBackground" in hope of getting a ripple effect. However, ripple effect does not work. Is there anyway to make the ripple effect work? As a workaround I wrapped the button with a FrameLayout and applied android:foreground="?attr/selectableItemBackground" to it, but in that case the ripple is rectangular and goes beyond button (as it is rounded).
xml:
<Button
android:id="#+id/reg_next"
android:layout_width="125dp"
android:layout_height="40dp"
android:text="#string/next"
android:layout_gravity="center"
android:textAllCaps="false"
android:textColor="#color/colorPrimary"
android:textSize="18sp"
android:background="#drawable/rounded_button_background"
android:foreground="?attr/selectableItemBackground"/>
rounded_button_background:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="#ebeff1"/> <!-- this one is ths color of the Rounded Button -->
<stroke android:width="1px" android:color="#979797" />
<corners
android:radius="20dp"
android:bottomLeftRadius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp"/>
</shape>

You need to create ripple drawable and set it as button background (without foreground attribute):
rounded_button_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#2793c9">
<item>
<shape
android:padding="10dp"
android:shape="rectangle">
<solid android:color="#ebeff1" /> <!-- this one is ths color of the Rounded Button -->
<stroke
android:width="1px"
android:color="#979797" />
<corners
android:bottomLeftRadius="20dp"
android:radius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />
</shape>
</item>
</ripple>
If you want support api bellow 21 (without ripple effect), add this drawable to directory drawable-v21 and in directory drawable create these files:
rounded_btn_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="#ebeff1" /> <!-- this one is ths color of the Rounded Button -->
<stroke
android:width="1px"
android:color="#979797" />
<corners
android:bottomLeftRadius="20dp"
android:radius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />
</shape>
rounded_btn_active.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="#2793c9" /> <!-- this one is ths color of the Rounded Button -->
<stroke
android:width="1px"
android:color="#979797" />
<corners
android:bottomLeftRadius="20dp"
android:radius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />
</shape>
rounded_button_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/rounded_btn_active" android:state_enabled="true" android:state_pressed="true" />
<item android:drawable="#drawable/rounded_btn_normal" android:state_enabled="true" />
</selector>

Related

drawableEnd attribute on Button doesn't accept shapes

Here is my Button:
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/status1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/large_text"
android:text="#string/offline"
android:drawableEnd="#drawable/online_dot"
android:drawableTint="#color/colorOnline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
online_dot.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#color/colorOnline" />
<stroke android:width="1dp" android:color="#color/colorLightBlack"/>
<corners android:radius="#dimen/circle_radius" />
</shape>
</item>
</selector>
online_dot.xml doesn't show. If I change drawableEnd to an actual image (not drawable) then it works. But I want to show a shape.
How can I fix this?
It happens because your shape hasn't a defined size.
You have to specify the size inside online_dot.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#color/colorOnline" />
<stroke android:width="1dp" android:color="#color/colorLightBlack"/>
<corners android:radius="#dimen/circle_radius" />
<!-- Specify the shape size here. -->
<size
android:height="20dp"
android:width="20dp" />
</shape>
</item>
</selector>

How to add ripple effect with gradient to button?

I created a button and I want to add ripple effect and gradient to that button!
Here is my Button code:
<Button
android:id="#+id/percentageButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/gradient"
android:gravity="center"
android:text="%"
android:textColor="#android:color/white"
android:textSize="30dp">
</Button>
Here is my gradient.xml file code
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners
android:radius="0dp"/>
<gradient
android:gradientRadius="100"
android:centerX="49%"
android:centerY="50%"
android:centerColor="#434343"
android:startColor="#0F0F0F"
android:endColor="#141414"
android:type="radial"/>
</shape>
I have tried all the possibilities but not getting how to achieve this.
To get the ripple effect when you press a button, simply change your button xml to include:
android:foreground="?attr/selectableItemBackground"
and to have a basic gradient on your button you can have:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="-90"
android:startColor="COLORHERE"
android:endColor="COLORHERE"
android:type="linear" />
</shape>
android:foreground didn't work for me in Lollipop and here are my xml drawable for the button.
Add button_background.xml to your drawable.
<?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" />
Note :
Attribute android:foreground has no effect on API levels lower than 23

Android Custom Button Ripple/pulse Effect

I have created a custom circular button using the following :
<Button
android:id ="#+id/StartButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
android:background="#drawable/button_bg_round"
android:padding="15dp"
android:textSize="30sp"
android:textStyle="bold"
android:textColor="#ffffff"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
Here button_bg_round is defined as below :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<stroke android:color="#ffffff" android:width="5dp" />
<solid android:color="#3aeaee"/>
<size android:width="200dp" android:height="200dp"/>
</shape>
</item>
</selector>
Now, I want to add a circular ripple/pulse effect/animation when the button is clicked. I tried to look for a possible solution on google and SO but couldn't find any related to such a button. Any help would be much appreciated.
You can make you drawable like this:
<?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/colorAccent"
tools:targetApi="lollipop"> <!-- ripple effect color -->
<item android:id="#android:id/background">
<shape android:shape="oval">
<stroke android:color="#ffffff" android:width="5dp" />
<solid android:color="#3aeaee"/>
<size android:width="200dp" android:height="200dp"/>
</shape>
</item>
</ripple>
where android:color inside ripple is the color of the effect.

Rectangle shape drawable won't show as checkbox selector item

I have defined a rectangle drawable like this:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dip"/>
<solid android:color="#FF000000" />
<stroke android:width="1dip" android:color="#color/service_checkbox_disabled_unchecked_stroke" />
</shape>
I can display the drawble as imageView without problems. However, it is supposed to be a drawble for one state of a checkbox. My selector for the checkbox button is defined like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="#drawable/bg_services_tick_unchecked_disabled" />
<item android:state_checked="false" android:drawable="#drawable/bg_services_tick_unchecked_disabled" />
</selector>
And finally my checkbox:
<CheckBox
android:id="#+id/cb_tariff_3_next_month_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/checkbox_services"
android:layout_centerHorizontal="true"/>
Can anyone tell, why does that not work? Thank you very much.
You must add a size node to the shape:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<size android:width="30dp" android:height="30dp" />
<solid android:color="#color/blueBase"/>
<stroke
android:width="1dp"
android:color="#color/blueDark" />
</shape>

How to create EditText with rounded corners?

How to create an EditText that has rounded corners instead of the default rectangular-shaped corners?
There is an easier way than the one written by CommonsWare. Just create a drawable resource that specifies the way the EditText will be drawn:
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/rounded_edittext.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:padding="10dp">
<solid android:color="#FFFFFF" />
<corners
android:bottomRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
</shape>
Then, just reference this drawable in your layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dip"
android:background="#drawable/rounded_edittext" />
</LinearLayout>
You will get something like:
Edit
Based on Mark's comment, I want to add the way you can create different states for your EditText:
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/rounded_edittext_states.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/rounded_focused" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#drawable/rounded_focused" />
<item
android:state_enabled="true"
android:drawable="#drawable/rounded_edittext" />
</selector>
These are the states:
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/rounded_edittext_focused.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="#FFFFFF"/>
<stroke android:width="2dp" android:color="#FF0000" />
<corners
android:bottomRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
</shape>
And... now, the EditText should look like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:background="#drawable/rounded_edittext_states"
android:padding="5dip" />
</LinearLayout>
Here is the same solution (with some extra bonus code) in just one XML file:
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/edittext_rounded_corners.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:state_focused="true">
<shape>
<solid android:color="#FF8000"/>
<stroke
android:width="2.3dp"
android:color="#FF8000" />
<corners
android:radius="15dp" />
</shape>
</item>
<item android:state_pressed="true" android:state_focused="false">
<shape>
<solid android:color="#FF8000"/>
<stroke
android:width="2.3dp"
android:color="#FF8000" />
<corners
android:radius="15dp" />
</shape>
</item>
<item android:state_pressed="false" android:state_focused="true">
<shape>
<solid android:color="#FFFFFF"/>
<stroke
android:width="2.3dp"
android:color="#FF8000" />
<corners
android:radius="15dp" />
</shape>
</item>
<item android:state_pressed="false" android:state_focused="false">
<shape>
<gradient
android:startColor="#F2F2F2"
android:centerColor="#FFFFFF"
android:endColor="#FFFFFF"
android:angle="270"
/>
<stroke
android:width="0.7dp"
android:color="#BDBDBD" />
<corners
android:radius="15dp" />
</shape>
</item>
<item android:state_enabled="true">
<shape>
<padding
android:left="4dp"
android:top="4dp"
android:right="4dp"
android:bottom="4dp"
/>
</shape>
</item>
</selector>
You then just set the background attribute to edittext_rounded_corners.xml file:
<EditText android:id="#+id/editText_name"
android:background="#drawable/edittext_rounded_corners"/>
Try this one,
Create rounded_edittext.xml file in your Drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="15dp">
<solid android:color="#FFFFFF" />
<corners
android:bottomRightRadius="0dp"
android:bottomLeftRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
<stroke android:width="1dip" android:color="#f06060" />
</shape>
Apply background for your EditText in xml file
<EditText
android:id="#+id/edit_expiry_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:background="#drawable/rounded_edittext"
android:hint="#string/shop_name"
android:inputType="text" />
You will get output like this
Thanks for Norfeldt's answer. I slightly changed its gradient for a better inner shadow effect.
<item android:state_pressed="false" android:state_focused="false">
<shape>
<gradient
android:centerY="0.2"
android:startColor="#D3D3D3"
android:centerColor="#65FFFFFF"
android:endColor="#00FFFFFF"
android:angle="270"
/>
<stroke
android:width="0.7dp"
android:color="#BDBDBD" />
<corners
android:radius="15dp" />
</shape>
</item>
Looks great in a light backgrounded layout..
By my way of thinking, it already has rounded corners.
In case you want them more rounded, you will need to:
Clone all of the nine-patch PNG images that make up an EditText background (found in your SDK)
Modify each to have more rounded corners
Clone the XML StateListDrawable resource that combines those EditText backgrounds into a single Drawable, and modify it to point to your more-rounded nine-patch PNG files
Use that new StateListDrawable as the background for your EditText widget
Just to add to the other answers, I found that the simplest solution to achieve the rounded corners was to set the following as a background to your Edittext.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#android:color/white"/>
<corners android:radius="8dp"/>
</shape>
With the Material Components Library you can use the MaterialShapeDrawable to draw custom shapes.
With a EditText you can do:
<EditText
android:id="#+id/edittext"
../>
Then create a MaterialShapeDrawable:
float radius = getResources().getDimension(R.dimen.default_corner_radius);
EditText editText = findViewById(R.id.edittext);
//Apply the rounded corners
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
.toBuilder()
.setAllCorners(CornerFamily.ROUNDED,radius)
.build();
MaterialShapeDrawable shapeDrawable =
new MaterialShapeDrawable(shapeAppearanceModel);
//Apply a background color
shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,R.color.white));
//Apply a stroke
shapeDrawable.setStroke(2.0f, ContextCompat.getColor(this,R.color.colorAccent));
ViewCompat.setBackground(editText,shapeDrawable);
It requires the version 1.1.0 of the library.
If you want only corner should curve not whole end, then use below code.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="10dp" />
<padding
android:bottom="3dp"
android:left="0dp"
android:right="0dp"
android:top="3dp" />
<gradient
android:angle="90"
android:endColor="#color/White"
android:startColor="#color/White" />
<stroke
android:width="1dp"
android:color="#color/Gray" />
</shape>
It will only curve the four angle of EditText.

Categories

Resources