1

I have a screen which have 2 edit text one edit text shows hour and other shows minute

enter image description here

I have number of validations that needs to be performed on this

hour edit Text

  • check if entered string if of 12 hour format
  • if user enter like 70 show error Tost and convert it ->07
  • if enter some number like 73 show error and remove last char and make it like ->07

minute Edit Text

  • value should be from 0>59

  • if entered 60 make it 00

  • if value entered is 80 ->show error ->convert it to 08

  • if value entered is 89 -> show error -> remove char and show as 08

     beginHour!!.addTextChangedListener(object : TextWatcher {
         override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
         override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
             if (p0.toString().isNotEmpty()) {
                 if (TextUtils.isDigitsOnly(p0.toString())) {
                     val hour = Integer.parseInt(p0.toString());
                     if (hour > maxHourValue || hour <= 0) {
                         shortToast(errorMessage)
                         beginHour!!.setText(beginHourString)
                     } else {
                         beginHourString = hour.toString()
                     }
                 } else {
                     shortToast(errorMessage)
                     beginHour!!.setText(beginHourString)
                 }
             } else {
                 beginHourString = ""
             }
         }
    
         override fun afterTextChanged(p0: Editable?) {
         }
     })
    
     beginHour!!.setOnFocusChangeListener { _, hasFocus ->
         if (!hasFocus) {
             try {
                 if (beginHour!!.text.isNullOrEmpty()) {
                     beginHour!!.setText("08")
                     beginHourString = "08"
                 }
                 val hour = 
             Integer.parseInt(beginHour!!.text.toString())
    
                if (value in 0..9) {
                   beginHour.setText("0$value")
             } else {
             beginHour.setText(value.toString())
              }
    
    
             } catch (exception: NumberFormatException) {
             }
         }
     }
    

can anyone suggest and guide me how to implement these validations

vivek panchal
  • 319
  • 1
  • 12
  • 1
    Use `textwatcher` Refer - https://stackoverflow.com/questions/8543449/how-to-use-the-textwatcher-class-in-android – Gaurav Chaudhari Feb 16 '22 at 19:00
  • @GauravChaudhari already tried it not able to achieve the exact result – vivek panchal Feb 17 '22 at 04:36
  • May I suggest: First use this property, `android:inputType="numberDecimal"` in your EditText? Next, use a regular expressions similar to `^(0[1-9]|1[0-2]):([0-5][0-9])$` for HH:MM. Finally, use other validations like range `if (i in 1..5) { /* code */ }` which check if `i <= 1 && i >= 5`. – acarlstein Feb 17 '22 at 05:23
  • @acarlstein as you can see these are two separate edit text one for hour and other for minutes. – vivek panchal Feb 17 '22 at 05:54
  • 1
    @vivekpanchal the fact that there are two separate EditText isn't an issue here. You set the flag `android:inputType="numberDecimal"` on both, so only numbers can be used. Then, you can either contatenate their values and validate, or you can split the regular expresion in two such as `^(0[1-9]|1[0-2])$` for the left, and `^([0-5][0-9])$` for the right. – acarlstein Feb 17 '22 at 14:15

1 Answers1

1

Use this logic

fun checkMinute(number: Int): Time {

    if (number == 60) return Time.Success("00")

    if (number in 0..59) {
        return Time.Success(number.toString())
    }

    return singleDigitTime(number)
}

fun checkHour(number: Int): Time {

    if (number in 1..12) {
        val df = DecimalFormat("00")
        val formattedString=df.format(number)
        return Time.Success(formattedString)
    }

    return singleDigitTime(number)
}


private fun singleDigitTime(number: Int): Time {
    if (number in 0..9) {
        return Time.Success(number.toString())
    }

    return Time.Error("0" + number.toString().substring(0, 1))
}

sealed class Time(data: String) {
    class Success(var data: String) : Time(data)
    class Error(var data: String) : Time(data)
}

solution with edittext

binding.etHour
            .textChangedStateFlow(700)
            .collect {
                val p0 = it.toString()
                val current = binding.etHour.text.toString().trim()
                if (current.isNotEmpty()){
                    val hour = Integer.parseInt(current);
                    checkHour(hour).let {
                        when (it) {
                            is Time.Error -> {
                                showToast()
                                Timber.d("error ${it.data.toString()}")
                                binding.etHour.updateText(it.data.toString())
                            }
                            is Time.Success -> {
                                Timber.d("success ${it.data.toString()}")
                                binding.etHour.updateText(it.data.toString())
                            }
                        }
                    }
                }

            }
Sagar Khurana
  • 184
  • 1
  • 2
  • 11