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:
Setting the Range: The
inputFilterNumberRange
extension function simplifies setting the allowed range for the EditText. It utilizes two other extension functions:filterMin
andInputFilterMax
.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.
- Setting an
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.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.
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)
}
}
}
<?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 - NumberPicker text size
- android kotlin - NumberPicker text color
- android kotlin - EditText space validation
- android kotlin - EditText email validation
- android kotlin - EditText select all on focus
- android kotlin - Show soft keyboard when EditText is focused
- android kotlin - EditText hide error
- android kotlin - EditText allow only certain characters
- android kotlin - EditText allow only numbers
- android kotlin - EditText allow only characters
- android kotlin - EditText allow only characters and numbers
- android kotlin - EditText input filter decimal
- android kotlin - EditText set max length programmatically
- android kotlin - EditText rounded corners programmatically
- android kotlin - EditText border color programmatically