Developing a user interface in Android applications often requires non-standard solutions, especially when it comes to styling controls. A standard rectangular button can look boring and stand out from modern Material Design, which is dominated by smooth shapes and soft shadows. Creating a round button is one of the most common tasks that developers face when creating layouts.

Fortunately, the development environment Android Studio provides several powerful tools for solving this task. You can use classic XML resources with drawable forms, modern library components, or even generate geometry programmatically through code on Material Components or even generate geometry programmatically through code on Kotlin or Java. Each method has its advantages: from ease of implementation to flexibility of animations.

In this article we will analyze in detail all the available methods. We will clearly show you how to change the fillet radius, how to make a button perfectly round (pill-shape), and how to avoid common mistakes when working with dimensions and indents. Whether you are using a legacy Button or an advanced MaterialButton, you will find a working solution here.

Using Drawable Shape XML Resources

The most classic and universal way to create a round button is to use an XML file with a description forms shape. This method works in all versions of Android and does not require heavy libraries. You need to create a file in the res/drawablefolder, for example circle_button.xml.

Inside this file you define the background geometry. To create a rectangle with rounded corners, use the tag corners. If you just need a round button (the so-called โ€œpill shapeโ€), the radius of the fillet should be equal to half the height of the element. This ensures that the left and right edges are completely rounded.

<shape xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="rectangle">

<solid android:color="@color/purple_500" />

<corners android:radius="50dp" />

</shape>

After creating the resource, it needs to be applied to the widget Button via the attribute android:background. Please note that standard Button has its own internal padding and shadows, which may conflict with your shape. To get a clean result, you often need to reset the default background or use android:backgroundTint in combination with a custom form.

๐Ÿ’ก

Use vector drawables instead of raster images for the button background to ensure ideal quality on screens with any pixel density (dpi).

โš ๏ธ Attention: When using attribute android:background on a standard widget Button you completely replace its native background, including ripple effects. To return the click animation, you need to wrap your form in a tag <ripple>.

Modern approach with MaterialButton

The library Material Components for Android has become the de facto standard for interface development. The component MaterialButton offers built-in corner rounding support without the need to create separate XML files for each button. This significantly speeds up the layout process and simplifies code support.

To control the shape of the button, special attributes namespace appare used. The app:cornerRadius attribute allows you to set the rounding radius directly in the layout. If you set the value to half the height of the button, it will become perfectly round. This solves the problem of size desynchronization, which often occurs when using drawable resources.

  • ๐Ÿ”˜ Use app:cornerRadius="24dp" to create a standard size pill button.
  • ๐ŸŽจ Change the background color through app:backgroundTint, not through android:backgroundto save the Material styles.
  • ๐ŸŒŠ The wave effect (ripple) when clicked is saved automatically without additional settings.

It is important to note the difference between android:background and app:backgroundTint. B MaterialButton he first attribute is intended for overlaying decorative elements on top of the main form, while the second changes the color of the background itself. Violating this rule may result in the button losing its shape or shadows.

๐Ÿ“Š Which component do you most often use for buttons?
Standard Button
MaterialButton
ImageButton
Custom View

Programmatically creating a round shape in code

Sometimes static XML is not enough, and you need to dynamically change the shape of the button at runtime. For example, if the rounding radius depends on the data received from the server or on the screen orientation. In such cases, we turn to the code at Kotlin or Java.

You can create an object GradientDrawable programmatically, give it a color and radius, and then set it as the background for your button. This approach gives the most flexibility, but requires more lines of code and makes the application logic harder to read. In addition, you lose the ability to preview your layout in the Android Studio editor.

val button = findViewById

When working with code, it is important to consider context and resources. Hardcoded pixel values โ€‹โ€‹(like 50f he example above) can look different on screens with different densities. It is always better to convert values from dp to px using class utilities TypedValue or context extensions.

Why should you not abuse UI code?

Frequently creating new Drawable objects in loops or when scrolling can lead to increased load on the garbage collector (Garbage Collector) and micro-freezes of the interface.

Subtleties of working with ImageButton and vectors

When it comes to buttons with icons inside, developers often choose ImageButton. You can make such a button round using the same methods: through background or backgroundTint. However, there is a nuance here with the positioning of the icon itself inside the circular area.

Standard ImageButton can cut off the edges of the image or incorrectly scale the vector if the attributes scaleTypeare not configured. For round buttons with icons, the optimal value is most often centerInside or fitCenterso that the graphics maintain proportions and do not protrude beyond the rounded corners.

ScaleType attribute Image behavior Suitable for a round button
centerCrop Fills the entire area, cutting off the edges No (risk of cutting off the icon)
fitXY Stretches to the size of the button No (distorts the proportions)
centerInside Fits completely, maintaining proportions Yes (recommended)
fitCenter Similar to centerInside, but with indents Yes

If you use MaterialButton s icon (attribute app:icon), the scaling problem is solved automatically. The component itself centers the vector and applies the necessary indents specified by the app:iconPaddingattribute. This is another argument in favor of using a modern library of materials.

Click and state animation (Ripple Effect)

A round button should not be static. Click feedback is a critical element of UX. In Android, the effect Ripple (wave) is responsible for this. When using custom drawable backgrounds, this effect disappears if you do not implement it manually.

To return the animation, you need to create a selector file in the folder res/drawable. Inside the tag ripple the color of the wave and the masking element (your round shape) are indicated. This ensures that the wave will propagate only within the boundaries of the circle, and not extend beyond the rectangular limits of the view.

  • ๐ŸŒŠ The color of the wave is set by the attribute android:color inside the ripple tag.
  • ๐ŸŽญ The shape mask is set by the tag <item android:id="@android:id/mask">.
  • ๐Ÿ‘† For Android versions below 5.0 (API 21), the ripple effect is not supported natively.

B MaterialButton all this magic happens under the hood. You just need to specify the color of the wave via app:rippleColor, and the system itself will limit the animation to the shape of the button. This saves time and reduces the risk of errors in XML markup.

โš ๏ธ Note: On older devices (Android 4.x), the tap effect may appear as a simple background color change without a wave animation. Always test the interface on emulators with different versions of the API.

Common errors and their solutions

Even experienced developers face problems when creating round elements. The most common mistake is a discrepancy between the radius of the rounding and the height of the button. If the radius is less than half the height, the button will appear as a rounded rectangle rather than an oval.

Another problem is with the text inside the button. Long text may extend beyond the visible area or run into rounded edges, creating visual noise. To avoid this, use the android:paddingStart attribute android:paddingEnd to create padding, or limit the maximum text width.

๐Ÿ’ก

A perfect round button is obtained only when the height of the element is fixed, and the rounding radius is strictly equal to half of this height.

It is also worth remembering about accessibility. Round buttons often have a smaller pressing area at the corners (since there are simply no corners). Make sure that the minimum button size according to Material Design guidelines is at least 48x48 dp so that the user can easily hit it with his finger.

โš ๏ธ Attention: Avoid using round buttons for long labels. This format is ideal for icons, short actions (OK, Cancel) or FAB (Floating Action Button), but is difficult to read with long text.

Frequently asked questions (FAQ)

How to make a button perfectly round if the text height changes?

To do this, you need to set a fixed button height (for example, 50dp) and set the rounding radius to 25dp. If you use wrap_content height, the shape will change along with the text, and the button will no longer be round when the content changes.

Why doesn't my MaterialButton become round?

Check if you are not overriding the background through the android:backgroundattribute. To change the shape, use app:cornerRadius. Also make sure that you are using the current version of the library Material Components in the file build.gradle.

Is it possible to make a round button without XML files?

Yes, this can be done entirely in code by creating an object GradientDrawable and setting it as the background. However, this approach makes it more difficult to maintain and prevents you from seeing the preview in the Android Studio layout editor.

How to add a shadow to a round button?

In MaterialButton the shadow is controlled by the app:elevationattribute. For standard buttons with a custom background, you need to use the tag layer-list in the drawable or include android:elevation i android:translationZ in the widget itself.

Is this method suitable for FloatingActionButton?

FloatingActionButton (FAB) is already round by default. You don't need to apply additional fillet styles to it. You only need to change its color through app:backgroundTint and the icon through app:srcCompat.