84

I want to create rounded buttons in an Android program. I have looked at How to create EditText with rounded corners?

What I want to achieve is:

  1. Rounded Edge Buttons
  2. Change Button background/appearance on different states (Like Onclick, Focus)
  3. Use my own PNG for the background and not create a shape.
Community
  • 1
  • 1
ControlAltDelete
  • 3,576
  • 5
  • 32
  • 50
  • 1
    http://nishantvnair.wordpress.com/2010/11/09/customize-button-in-android/ – Sergey Benner Feb 17 '12 at 20:16
  • Google have new framework, new technologies is better [Jetpack Compose](https://stackoverflow.com/questions/6054562/how-to-make-the-corners-of-a-button-round/64087445#64087445) – Ucdemir Sep 27 '20 at 10:39

10 Answers10

137

You can do a rounded corner button without resorting to an ImageView.

A background selector resource, button_background.xml:

<?xml version="1.0" encoding="utf-8" ?> 
     <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <!--  Non focused states 
      --> 
      <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_unfocused" /> 
      <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_unfocused" /> 
     <!--  Focused states 
      --> 
      <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_focus" /> 
      <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_focus" /> 
     <!--  Pressed 
      --> 
      <item android:state_pressed="true" android:drawable="@drawable/button_press" /> 
    </selector>

For each state, a drawable resource, e.g. button_press.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <stroke android:width="1dp" android:color="#FF404040" /> 
  <corners android:radius="6dp" /> 
  <gradient android:startColor="#FF6800" android:centerColor="#FF8000" android:endColor="#FF9700" android:angle="90" /> 
</shape>

Note the corners element, this gets you rounded corners!

Then set the background drawable on the button:

android:background="@drawable/button_background"

EDIT (9/2018): The same technique can be used to create a circular button. A circle is really just a square button with radius size set to 1/2 the side of the square

Additionally, in the example above the stroke and gradient aren't necessary elements, they are just examples and ways that you'll be able to see the rounded corner shape

weston
  • 54,145
  • 21
  • 145
  • 203
CSmith
  • 13,318
  • 3
  • 39
  • 42
  • 1
    CSMith. I got the selector working. I am a bit confused by the second part as to where to put the code. Do I create a separate xml file. If so how do i call it? I am assuming for the button, I still set it's background to @drawable/button_background... Thx – ControlAltDelete Feb 17 '12 at 22:04
  • yes, set the background to button_background, and you'll have an xml file for each "state" in your selection, the second part is an example button_press.xml. – CSmith Feb 21 '12 at 17:34
  • 1
    CSmith. So where is this separate xml file being called. In the example above you have the background set to a drawable object and that works great to get the background to change on interaction. However, the button is not rounded unless you create the png. with rounded corners and use nine patch to avoid distortion. – ControlAltDelete Feb 22 '12 at 00:53
  • What if I need to add custom font to my button text too? – Garima Tiwari May 23 '13 at 08:34
  • The background drawable selector has nothing to do with the text font. This android:background could be used on both a standard Button and an ImageButton. – CSmith May 23 '13 at 12:22
  • So, I am really new at this but, if I understand you correctly CSmith you're saying to replicate the resource and rename (and tweak) it for each of the 4 button states? So, total of 5 resource files for this case? – Christian Bongiorno Jun 21 '13 at 16:27
  • @ChristianBongiorno, assuming you want different styling for the various button states (i.e. selected, pressed, etc), you'd need separate drawable resources for each. – CSmith Jul 22 '13 at 13:02
  • 2
    I'm pretty new to android development and this question might come out pretty damn naive: Which `drawable` folder should I add the XML file to? I've got four different `drawable` folders: `drawable-hdpi`; `drawable-mdpi`; `drawable-xhdpi`; `drawable-xxhdpi`. – ikartik90 Sep 29 '14 at 17:42
  • 3
    @ikartik90, use drawable. The other folders in general are used to override settings found in the "base" drawable folder for density specific assets or settings, and in this example there aren't any density specific overrides present. – CSmith Sep 29 '14 at 18:00
  • Why are there 2 of each? – CodyBugstein Sep 30 '14 at 16:17
  • for me. at present adding a selector to a button does nothing. i can get the selector added to a textview and use it like a button and it works fine. just doesnt seem to change the colouring etc of the button? – filthy_wizard Mar 24 '19 at 14:25
  • what about button_unfocused and button_focus drawables? – erik.aortiz Nov 29 '22 at 21:10
87

If you need a rounded button in Android, then create an XML file "RoundShapeBtn.xml" as drawable.

 <?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="#6E6E6E"/> <!-- this one is ths color of the Rounded Button -->
  <corners
   android:bottomRightRadius="10dp"
   android:bottomLeftRadius="10dp"
   android:topLeftRadius="10dp"
   android:topRightRadius="10dp"/>
</shape>

Add this to your button code:

android:background="@drawable/RoundShapeBtn"
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Pir Fahim Shah
  • 10,505
  • 1
  • 82
  • 81
18

create xml file in drawable folder in android like :

rounded_button.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">

    <corners android:radius="20dp"/> // if you want clear round shape then make radius size is half of your  button`s height.
    <solid android:color="#EEFFFFFF"/> // Button Colour
    <padding
        android:bottom="5dp"
        android:left="10dp"
        android:right="10dp"
        android:top="5dp"/>

</shape>

Now this xml file as your buttons background.

 <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/rounded_button"
        android:text="@string/button_text"
        android:textColor="@color/black"/>
Arunendra
  • 2,034
  • 26
  • 22
  • This is a what most people are looking for actually. Very curved smooth rectangular edges. How can I put a shadow on the button? Thanks! – S bruce Mar 08 '16 at 12:04
  • 1
    Stellar! If anyone is annoyed at having to make separate rounded button XMLs to get different colors, you can remove the `solid android:color` from the drawable XML, and instead specify colors using `android:backgroundTint` for each `Button` – Kartik Chugh Jan 12 '18 at 00:34
  • @K_7 if you do that, you lose the elevation and shadow. just follow this one you would get elevation and shadow when you hold on the button. – Jeffrey Liu Apr 05 '18 at 21:13
6

Extend ImageView like so:

public class RoundedImageView extends ImageView {
  private static final String TAG = "RoundedImageView";

  private float mRadius = 0f;

  public RoundedImageView(Context context) {
    super(context);
  }

  public RoundedImageView(Context context, AttributeSet attrs) {
    super(context, attrs);

    // retrieve styles attributes
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedView);
    mRadius = a.getDimension(R.styleable.RoundedView_radius, 0f);
    a.recycle();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    // only do this if we actually have a radius
    if(mRadius > 0) {
      RectF rect = new RectF(0, 0, getWidth(), getHeight());
      Path clipPath = new Path();
      clipPath.addRoundRect(rect, mRadius, mRadius, Path.Direction.CW);
      canvas.clipPath(clipPath);
    }
    super.onDraw(canvas);
  }
}

And apply your normal background resource to it and it should be clipped with rounded corners.

Cody Caughlan
  • 32,456
  • 5
  • 63
  • 68
4

This can be done using the corner attribute. Look at the below xml.

<item>
    <shape android:shape="rectangle" >
        <stroke
            android:height="1.0dip"
            android:width="1.0dip"
            android:color="#ffee82ee" />

        <solid android:color="#ffee82ee" />

        <corners
            android:bottomLeftRadius="102.0dip"
            android:bottomRightRadius="102.0dip"
            android:radius="102.0dip"
            android:topLeftRadius="102.0dip"
            android:topRightRadius="102.0dip" />
    </shape>
</item>

Rohit Goyal
  • 550
  • 8
  • 9
4

It's much better to put the button states and shapes in 1 xml selector file. That should make your app run faster/better. Try this (courtesy of Introduction to Android Application Development). Not spamming here just showing this isn't my code.

    <?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="12dip" />
     <stroke android:width="1dip" android:color="#333333" />
     <gradient android:angle="-90" android:startColor="#333333"      android:endColor="#555555"  />            
    </shape>
    </item>
    <item android:state_focused="true">
    <shape android:shape="rectangle"  >
     <corners android:radius="12dip" />
     <stroke android:width="1dip" android:color="#333333" />
     <solid android:color="#58857e"/>       
    </shape>
    </item>  
    <item >
    <shape android:shape="rectangle"  >
     <corners android:radius="12dip" />
     <stroke android:width="1dip" android:color="#333333" />
     <gradient android:angle="-90" android:startColor="#333333" android:endColor="#555555" />            
    </shape>
    </item>

    </selector>

P.S.-design tip: gradients and rounded rectangles are best used when you can hardly tell they are there-use wisely.

3

It is recommended by Google that you do not mimic UI elements from other platforms. I wouldn't put rounded iOS style buttons in an Android application.

Christopher Perry
  • 38,891
  • 43
  • 145
  • 187
  • 67
    It's not our fault that the devs decided to put an ugly UI as the standard. – Yehonatan May 21 '14 at 16:14
  • This is a bit after the old, but I thought I'd add to anyone reading that my previous company's app was nearly not featured on the app store due to a lot of iOS UI styling. We had to revise and put in the appropriate Material design considerations. Always important to follow the guidelines! – lase Nov 29 '17 at 14:22
  • 2
    @lase completely disagree the guidelines are just that, they are not hard rules – martinseal1987 Jul 07 '19 at 15:53
  • @martinseal1987 well, as loose as rules may be, i'm just providing future readers anecdotal evidence that the platform holders *do* care about style consistency, which is perhaps obvious through the answer's link to the style guide and the large section on cross platform implementation. feel free to roll the dice! – lase Jul 08 '19 at 16:59
  • @lase the playstore would never deny your app for not sticking to the guidelines, they are not rules in any sense of the word – martinseal1987 Jul 09 '19 at 13:35
  • @martinseal1987 getting your application "featured" and "approved" are entirely different concepts. – lase Jul 09 '19 at 20:30
  • @lase an important distinction I honestly missed, however games would be an easy exception to your point – martinseal1987 Jul 10 '19 at 07:14
  • Lemme just go tell my UI designers... – Chris Rollins Dec 02 '21 at 23:51
2

Rounded buttons can be creating using ring shape drawable also, see http://www.zoftino.com/android-shape-drawable-examples

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="0dp"
    android:shape="ring"
    android:thickness="40dp"
    android:useLevel="false">
    <solid android:color="@color/colorPrimary" />
    <padding android:bottom="50dp"
        android:left="16dp"
        android:right="16dp"
        android:top="50dp"/>
</shape>
Arnav Rao
  • 6,692
  • 2
  • 34
  • 31
2

Create Drawable resource named btnOval-->then past code ;

 <?xml version="1.0" encoding="utf-8"?>
      <shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="oval"  
android:padding="10dp">   
      <solid android:color="#6E6E6E"/> 
    </shape>

and user inside button tag like,

<Button
andorid:width=""
android:hieght=""
android:background="@Drawable/btnOval"
/>
Ashik Azeez
  • 404
  • 5
  • 8
0

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>
Udara Abeythilake
  • 1,215
  • 1
  • 20
  • 31