Android
EditText
Numeric Input
User Interface
Android Development

How do you set EditText to only accept numeric values in Android?

Master System Design with Codemia

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

Introduction

Restricting an EditText to numeric input in Android uses the android:inputType XML attribute or setInputType() in code. Setting inputType="number" shows a numeric keyboard and rejects non-digit characters. For decimal numbers, use numberDecimal. For negative numbers, use numberSigned. For phone numbers, use phone. You can also use InputFilter for custom validation rules like limiting digit count or value ranges. This article covers XML and programmatic approaches with Kotlin and Java examples.

XML: inputType Attribute

xml
1<!-- Integer only (0-9) -->
2<EditText
3    android:id="@+id/etAge"
4    android:layout_width="match_parent"
5    android:layout_height="wrap_content"
6    android:inputType="number"
7    android:hint="Enter age" />
8
9<!-- Decimal numbers (0-9 and decimal point) -->
10<EditText
11    android:id="@+id/etPrice"
12    android:layout_width="match_parent"
13    android:layout_height="wrap_content"
14    android:inputType="numberDecimal"
15    android:hint="Enter price" />
16
17<!-- Signed numbers (allows negative) -->
18<EditText
19    android:id="@+id/etTemperature"
20    android:layout_width="match_parent"
21    android:layout_height="wrap_content"
22    android:inputType="numberSigned|numberDecimal"
23    android:hint="Enter temperature" />
24
25<!-- Phone number (0-9, +, -, (, ), etc.) -->
26<EditText
27    android:id="@+id/etPhone"
28    android:layout_width="match_parent"
29    android:layout_height="wrap_content"
30    android:inputType="phone"
31    android:hint="Enter phone number" />

inputType="number" shows the numeric keyboard and filters input to digits only. Combine flags with | for decimal and signed input.

Programmatic (Kotlin)

kotlin
1import android.text.InputType
2
3// Integer only
4editText.inputType = InputType.TYPE_CLASS_NUMBER
5
6// Decimal
7editText.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
8
9// Signed decimal
10editText.inputType = InputType.TYPE_CLASS_NUMBER or
11    InputType.TYPE_NUMBER_FLAG_DECIMAL or
12    InputType.TYPE_NUMBER_FLAG_SIGNED
13
14// Phone
15editText.inputType = InputType.TYPE_CLASS_PHONE

Programmatic (Java)

java
1// Integer only
2editText.setInputType(InputType.TYPE_CLASS_NUMBER);
3
4// Decimal
5editText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
6
7// Signed decimal
8editText.setInputType(InputType.TYPE_CLASS_NUMBER
9| InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED); ``` ## Using digits Attribute ```xml <!-- Only allow specific characters --> <EditText android:id="@+id/etPIN" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number" android:digits="0123456789" android:maxLength="4" android:hint="Enter 4-digit PIN" /> <!-- Only allow hex digits --> <EditText android:id="@+id/etHex" android:layout_width="match_parent" android:layout_height="wrap_content" android:digits="0123456789ABCDEFabcdef" android:hint="Enter hex value" /> ``` `android:digits` restricts input to the specified characters only. Characters not in the string are silently rejected. ## InputFilter for Custom Validation ```kotlin import android.text.InputFilter // Limit to a range (e.g., 1-100) class MinMaxFilter(private val min: Int, private val max: Int) : InputFilter { override fun filter( source: CharSequence, start: Int, end: Int, dest: android.text.Spanned, dstart: Int, dend: Int ): CharSequence? { try { val input = (dest.toString() + source.toString()).toInt() if (input in min..max) return null  // Accept } catch (e: NumberFormatException) { // Reject } return ""  // Reject the input } } // Apply the filter editText.filters = arrayOf(MinMaxFilter(1, 100)) // Combine with max length filter editText.filters = arrayOf( MinMaxFilter(1, 100), InputFilter.LengthFilter(3) ) ``` ## TextWatcher for Real-Time Validation ```kotlin import android.text.TextWatcher import android.text.Editable editText.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { val text = s?.toString() ?: return if (text.isEmpty()) return try { val value = text.toDouble() if (value > 999.99) { editText.error = "Maximum value is 999.99" } } catch (e: NumberFormatException) { editText.error = "Invalid number" } } }) ``` `TextWatcher` provides real-time feedback without blocking input. Use `editText.error` to show inline error messages. ## Jetpack Compose ```kotlin import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.TextField import androidx.compose.runtime.* import androidx.compose.ui.text.input.KeyboardType @Composable fun NumericTextField() { var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { newValue -> // Filter to digits only text = newValue.filter { it.isDigit() } }, label = { Text("Enter number") }, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Number ) ) } // Decimal input @Composable fun DecimalTextField() { var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { newValue -> // Allow digits and one decimal point if (newValue.isEmpty() || newValue.matches(Regex("^\\d*\\.?\\d*$"))) { text = newValue } }, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Decimal ) ) } ``` In Compose, `KeyboardType.Number` shows the numeric keyboard, and `onValueChange` filters invalid characters. ## Common Pitfalls * **inputType does not prevent paste**: Users can paste non-numeric text from the clipboard even with `inputType="number"`. Use an `InputFilter` or `TextWatcher` to validate pasted content. * **numberDecimal allows multiple decimal points on some keyboards**: Some third-party keyboards do not enforce single decimal point. Validate in `afterTextChanged` or `onValueChange` to reject multiple dots. * **Forgetting numberSigned for negative values**: `inputType="number"` only allows positive digits. If negative numbers are valid (temperature, coordinates), add `numberSigned` to the input type. * **maxLength not applying to programmatic setText**: `android:maxLength` only limits user input. Calling `setText()` in code ignores the limit. Validate in code as well if you set text programmatically. * **Keyboard type vs input validation**: `inputType` controls the keyboard shown and provides basic filtering, but it is not a security measure. Always validate the final value before processing — never trust client-side input alone. ## Summary * Use `android:inputType="number"` in XML for integer-only input with numeric keyboard * Add `numberDecimal` and `numberSigned` flags for decimal and negative numbers * Use `android:digits` to restrict to a specific set of allowed characters * Use `InputFilter` for range validation and `TextWatcher` for real-time feedback * In Jetpack Compose, combine `KeyboardType.Number` with `onValueChange` filtering * Always validate the final value server-side — `inputType` is a UI hint, not a security measure

Course illustration
Course illustration

All Rights Reserved.