android kotlin - EditText limit number range

Limiting Number Range Input in an EditText (Android Kotlin)

This code demonstrates a way to restrict the number range a user can enter within an EditText in an Android application written in Kotlin. It allows for a user-defined minimum and maximum value.

The code is divided into separate functionalities:

  1. Setting the Range: The inputFilterNumberRange extension function simplifies setting the allowed range for the EditText. It utilizes two other extension functions: filterMin and InputFilterMax.

  2. Enforcing Minimum Value: The filterMin function ensures that the user-entered value doesn't fall below the minimum limit. It achieves this by:

    • Setting an onFocusChangeListener that checks the input on focus loss.
    • Setting an onEditorActionListener that checks the input on pressing "Done" on the keyboard.
    • If the input is less than the minimum, it sets the text to the minimum value and changes the underline color to red for visual feedback.
  3. Enforcing Maximum Value: The InputFilterMax class is a custom InputFilter that restricts the user's input to not exceed the maximum defined range. It checks the entered characters and the resulting number, allowing only valid inputs within the range.

  4. Visual Cues and Keyboard Management: The code utilizes functions to:

    • Change the underline color of the EditText based on validity (green for valid, red for invalid).
    • Hide the soft keyboard programmatically when the user finishes entering the number.

Summary

This code provides a user-friendly experience for number input within a specific range. It offers a clean separation of concerns with extension functions and a custom InputFilter class, making it reusable and easy to understand. The visual cues and keyboard management further enhance the user experience.


MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.content.Context.INPUT_METHOD_SERVICE
import android.graphics.BlendMode
import android.graphics.BlendModeColorFilter
import android.graphics.Color
import android.graphics.PorterDuff
import android.os.Build
import android.os.Bundle
import android.text.InputFilter
import android.text.Spanned
import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast


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 input filter number range
        editText.inputFilterNumberRange(6..90)

        // show the rule
        textView.text = "Input number range 6 to 90"
        textView.append("\n\nIf user put less than" +
                " minimum then it set to minimum.")
    }
}


// extension function to filter edit text number range
fun EditText.inputFilterNumberRange(range: IntRange){
    filterMin(range.first)
    filters = arrayOf<InputFilter>(InputFilterMax(range.last))
}


// class to input filter maximum number
class InputFilterMax(private var max: Int) : InputFilter {
    override fun filter(
        p0: CharSequence, p1: Int, p2: Int, p3: Spanned?, p4: Int, p5: Int
    ): CharSequence? {
        try {
            val replacement = p0.subSequence(p1, p2).toString()
            val newVal = p3.toString().substring(0, p4) +
                    replacement + p3.toString()
                .substring(p5, p3.toString().length)
            val input = newVal.toInt()
            if (input <= max) return null
        } catch (e: NumberFormatException) { }
        return ""
    }
}


// extension function to filter edit text minimum number
fun EditText.filterMin(min: Int){
    onFocusChangeListener = View.OnFocusChangeListener { view, b ->
        if (!b) {
            // set minimum number if inputted number less than minimum
            setTextMin(min)
            // hide soft keyboard on edit text lost focus
            context.hideSoftKeyboard(this)
        }
    }

    setOnEditorActionListener { v, actionId, event ->
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            // set minimum number if inputted number less than minimum
            setTextMin(min)

            // hide soft keyboard on press action done
            context.hideSoftKeyboard(this)
        }
        false
    }
}


// extension function to set edit text minimum number
fun EditText.setTextMin(min: Int){
    try {
        val value = text.toString().toInt()
        setUnderlineColor(Color.GREEN)
        if (value < min){
            setText("$min")
            setUnderlineColor(Color.RED)
        }
    }catch (e: Exception){
        setUnderlineColor(Color.RED)
        setText("$min")
    }
}


// extension function to hide soft keyboard programmatically
fun Context.hideSoftKeyboard(editText: EditText){
    (getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).apply {
        hideSoftInputFromWindow(editText.windowToken, 0)
    }
}


// extension function to set/change edit text underline color
fun EditText.setUnderlineColor(color: Int){
    background.mutate().apply {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
            colorFilter = BlendModeColorFilter(color, BlendMode.SRC_IN)
        }else{
            setColorFilter(color, PorterDuff.Mode.SRC_IN)
        }
    }
}
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="number"
        android:padding="12dp"
        android:textSize="30sp"
        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
More android kotlin tutorials