Android Kotlin: EditText input filter decimal

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:

  1. 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.

  2. inputFilterDecimal extension function: This function is an extension for the EditText class. It takes two arguments: maxDigitsIncludingPoint and maxDecimalPlaces. It sets an array of filters to the EditText, where the only element is a DecimalDigitsInputFilter object instantiated with the provided arguments. In case of a PatternSyntaxException, the function disables the EditText and sets its hint to the exception message.

  3. DecimalDigitsInputFilter class: This class implements the InputFilter interface. It defines a regular expression pattern based on the provided maxDigitsIncludingPoint and maxDecimalPlaces values. The filter 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.


MainActivity.kt

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
    }
}
activity_main.xml

<?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 input filter decimal
More android kotlin tutorials