Android Development
TextView
User Interface Design
Coding Tips
Android Layouts

How to put a border around an Android TextView?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The usual way to draw a border around a TextView in Android is to assign a shape drawable as its background. That keeps the styling in resources, makes it reusable, and works better than trying to fake a border with extra wrapper views.

Use a Shape Drawable in XML

For a fixed border style, XML is the cleanest option. Create a drawable resource and define both the fill and stroke.

xml
1<!-- res/drawable/textview_border.xml -->
2<shape xmlns:android="http://schemas.android.com/apk/res/android"
3    android:shape="rectangle">
4
5    <solid android:color="@android:color/white" />
6    <stroke
7        android:width="1dp"
8        android:color="#222222" />
9    <corners android:radius="6dp" />
10    <padding
11        android:left="12dp"
12        android:top="8dp"
13        android:right="12dp"
14        android:bottom="8dp" />
15</shape>

Then apply it to the TextView.

xml
1<TextView
2    android:id="@+id/statusText"
3    android:layout_width="wrap_content"
4    android:layout_height="wrap_content"
5    android:background="@drawable/textview_border"
6    android:text="Ready" />

This is the most maintainable approach when the border does not change dynamically.

Use a GradientDrawable in Code for Dynamic Styling

If border color, width, or radius changes at runtime, create the background programmatically.

kotlin
1val statusText = findViewById<TextView>(R.id.statusText)
2
3val background = GradientDrawable().apply {
4    shape = GradientDrawable.RECTANGLE
5    setColor(Color.WHITE)
6    setStroke(2, Color.parseColor("#D32F2F"))
7    cornerRadius = 12f
8}
9
10statusText.background = background

This is useful for states such as validation errors, selected chips, or live status indicators.

Remember Padding and Background Interaction

Borders often look wrong not because the stroke is wrong, but because the text sits too close to the edge. If the drawable already defines padding, be careful not to double it with large android:padding values on the TextView itself.

A good visual result usually depends on three things together:

  • stroke width
  • corner radius
  • inner spacing around the text

Testing only the stroke color is usually not enough.

Handle Stateful Borders with Selectors

If the border should change for pressed, selected, or focused states, use a selector that swaps drawables.

xml
1<!-- res/drawable/textview_stateful_background.xml -->
2<selector xmlns:android="http://schemas.android.com/apk/res/android">
3    <item android:state_selected="true" android:drawable="@drawable/textview_border_selected" />
4    <item android:drawable="@drawable/textview_border" />
5</selector>

Then toggle the state in code or through view state changes. This is cleaner than rebuilding the background every time a small state changes.

Material Components Alternative

If the app already uses Material Components, sometimes a plain TextView with a custom background is still enough. But if the control is behaving more like a chip, badge, or outlined input, consider using a more specialized component instead of styling TextView beyond recognition.

That keeps your UI code easier to maintain and makes accessibility behavior more predictable.

Keep Border Resources Reusable

If several screens need the same outlined label style, keep the drawable generic and vary only theme colors or state selectors. Centralizing border resources avoids small visual mismatches that accumulate over time across multiple layouts.

That also simplifies maintenance.

Common Pitfalls

  • Using nested layout wrappers just to simulate a border instead of a drawable background.
  • Forgetting padding, which makes the text appear cramped inside the border.
  • Hard-coding colors in several places instead of using reusable drawables or theme values.
  • Rebuilding drawable objects repeatedly when a selector resource would handle simple states.
  • Styling a TextView to mimic a different component when a more appropriate Material widget already exists.

Summary

  • The standard Android solution is a shape drawable assigned as the TextView background.
  • Use XML for fixed styles and GradientDrawable for runtime changes.
  • Balance stroke, corner radius, and padding together for a clean result.
  • Use selectors when the border needs state-based styling.
  • Prefer the right component if the UI starts behaving like more than a simple TextView.

Course illustration
Course illustration

All Rights Reserved.