This code demonstrates how to create a custom input filter for an EditText in an Android application written in Kotlin. This filter restricts the user's input to decimal numbers with a specific format.
The code is divided into three parts:
MainActivity.kt: This file defines the main activity of the application. It fetches references to the EditText and TextView widgets from the layout and applies the
inputFilterDecimal
extension function to the EditText. It also displays information about the maximum digits and decimal places allowed.inputFilterDecimal extension function: This function is an extension for the EditText class. It takes two arguments:
maxDigitsIncludingPoint
andmaxDecimalPlaces
. It sets an array of filters to the EditText, where the only element is aDecimalDigitsInputFilter
object instantiated with the provided arguments. In case of aPatternSyntaxException
, the function disables the EditText and sets its hint to the exception message.DecimalDigitsInputFilter class: This class implements the
InputFilter
interface. It defines a regular expression pattern based on the providedmaxDigitsIncludingPoint
andmaxDecimalPlaces
values. Thefilter
method of this class checks the entered text against the pattern. If the text doesn't match the pattern, it returns an empty string, effectively preventing the character from being added.
Summary
This code provides a reusable solution for restricting user input in an EditText to a specific decimal format. The inputFilterDecimal
extension function simplifies the process of applying the filter and handles potential exceptions. The DecimalDigitsInputFilter
class implements the filtering logic using a regular expression. This approach ensures that only valid decimal numbers are entered into the EditText.
package com.cfsuman.kotlintutorials
import android.app.Activity
import android.os.Bundle
import android.text.InputFilter
import android.text.Spanned
import android.widget.EditText
import android.widget.TextView
import java.util.regex.Matcher
import java.util.regex.Pattern
import java.util.regex.PatternSyntaxException
class MainActivity : Activity() {
private lateinit var editText:EditText
private lateinit var textView:TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// get the widgets reference from XML layout
editText = findViewById(R.id.editText)
textView = findViewById(R.id.textView)
// apply edit text decimal input filter
editText.inputFilterDecimal(
// this values must be positive (0+) unless it throw exception
maxDigitsIncludingPoint = 5,
maxDecimalPlaces = 2
)
textView.text = "Max digits including point : 5"
textView.append("\nMax decimal places : 2")
}
}
// extension function to input filter edit text decimal digits
fun EditText.inputFilterDecimal(
// maximum digits including point and without decimal places
maxDigitsIncludingPoint: Int,
maxDecimalPlaces: Int // maximum decimal places
){
try {
filters = arrayOf<InputFilter>(
DecimalDigitsInputFilter(
maxDigitsIncludingPoint, maxDecimalPlaces)
)
}catch (e: PatternSyntaxException){
isEnabled = false
hint = e.message
}
}
// class to decimal digits input filter
class DecimalDigitsInputFilter(
maxDigitsIncludingPoint: Int, maxDecimalPlaces: Int
) : InputFilter {
private val pattern: Pattern = Pattern.compile(
"[0-9]{0," + (maxDigitsIncludingPoint - 1) + "}+((\\.[0-9]{0,"
+ (maxDecimalPlaces - 1) + "})?)||(\\.)?"
)
override fun filter(
p0: CharSequence?,p1: Int,p2: Int,p3: Spanned?,p4: Int,p5: Int
): CharSequence? {
p3?.apply {
val matcher: Matcher = pattern.matcher(p3)
return if (!matcher.matches()) "" else null
}
return null
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="#DCDCDC"
android:padding="32dp">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:inputType="numberDecimal"
android:padding="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.12" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:fontFamily="sans-serif-condensed-medium"
android:gravity="center"
android:padding="8dp"
android:textColor="#4F42B5"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText"
tools:text="TextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
- android kotlin - EditText limit number range
- android kotlin - EditText set max length programmatically
- android kotlin - EditText rounded corners programmatically
- android kotlin - EditText border color programmatically
- android kotlin - EditText change underline color programmatically
- android kotlin - EditText focus change listener
- android kotlin - EditText hide keyboard on lost focus
- android kotlin - EditText enter key listener
- android kotlin - EditText listener
- android kotlin - EditText TextWatcher
- android kotlin - Get raw resource uri
- android kotlin - Button with icon
- android kotlin - Resize ImageView programmatically
- android kotlin - Circular ImageView with border
- android kotlin - Circular ImageView programmatically