Как я могу сделать так, чтобы мое приложение для Android не зависало, когда вызываемые значения TextEdit оставлены пустыми? (Kotlin)

#android #kotlin

#Android #kotlin

Вопрос:

Я работаю над простым приложением tip calculator, и пока оно работает хорошо. Однако, если мои текстовые изменения пусты, мое приложение принудительно закрывается при нажатии кнопки «рассчитать». Я не смог найти решение для этого, и все, что я нахожу в Интернете или в StackOverflow, находится на Java.

Это функция, которая вызывается при нажатии моей кнопки:

 @SuppressLint("UseSwitchCompatOrMaterialCode")
    fun calculateTip() {
        var mealCost: Double = cost_of_service.text.toString().toDouble()
        var splitNum: Double = split_num.text.toString().toDouble()

        val selectedId = tip_options.checkedRadioButtonId
        val tipPercentage = when(selectedId) {
            R.id.option_twenty_percent -> 0.20
            R.id.option_eighteen_percent -> 0.18
            else -> 0.15}

        //original values
        var tip: Double = tipPercentage * mealCost
        var addedCost: Double = tip   mealCost
        var split: Double = addedCost / splitNum

        //finds some views
        val switch: Switch = findViewById(R.id.round_up_switch)
        val result: TextView = findViewById(R.id.tip_result)
        val total: TextView = findViewById(R.id.total_cost)
        val splitResult: TextView = findViewById(R.id.split_cost)
        val roundUp = switch.isChecked
        var splitString: String = split.toString()

        //if roundup switch is checked, rounds tip up
        if (roundUp) {
            tip = kotlin.math.ceil(tip)
            addedCost = kotlin.math.ceil(addedCost)
            split = kotlin.math.ceil(split)}

        //formats the tip to $
        val formattedTip = NumberFormat.getCurrencyInstance().format(tip)
        val formattedCost = NumberFormat.getCurrencyInstance().format(addedCost)
        val formattedSplit = NumberFormat.getCurrencyInstance().format(split)

        //changes the textViews in the app
        result.text = getString(R.string.tip_amount, formattedTip)
        total.text = getString(R.string.total_amount, formattedCost)
        splitResult.text = getString(R.string.split_cost, formattedSplit)
    }
  

При этом ошибка, которая отображается в Logcat, когда я нажимаю ее, не заполняя значения TextEdit.

 2020-10-09 17:59:49.446 21872-21872/com.gradient.tiptime E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.gradient.tiptime, PID: 21872
    java.lang.NumberFormatException: empty String
        at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
        at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
        at java.lang.Double.parseDouble(Double.java:538)
        at com.gradient.tiptime.MainActivity.calculateTip(MainActivity.kt:25)
        at com.gradient.tiptime.MainActivity$onCreate$1.onClick(MainActivity.kt:19)
        at android.view.View.performClick(View.java:7192)
        at android.view.View.performClickInternal(View.java:7166)
        at android.view.View.access$3500(View.java:824)
        at android.view.View$PerformClick.run(View.java:27592)
        at android.os.Handler.handleCallback(Handler.java:888)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:213)
        at android.app.ActivityThread.main(ActivityThread.java:8178)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
  

Прошу прощения за длинный вопрос. Я уже некоторое время пытаюсь решить эту проблему, но не могу найти ответ. Заранее благодарим вас за любую помощь!

Ответ №1:

Проблема заключается в первых двух строках calculateTip метода

 var mealCost: Double = cost_of_service.text.toString().toDouble()
var splitNum: Double = split_num.text.toString().toDouble()
  

Если EditTexts пусты cost_of_service.text.toString() , возвращает пустую строку, преобразование пустой строки в Double вызывает сбой.

Чтобы решить эту проблему, вы могли бы использовать .toDoubleOrNull() вместо .toDouble() и написать что-то вроде этого:

 var mealCost: Double = cost_of_service.text.toString().toDoubleOrNull() ?: 0.0
var splitNum: Double = split_num.text.toString().toDoubleOrNull() ?: 1.0
  

(Для splitNum установлено значение 1.0, поскольку вы не хотите делить на 0)

Если вы не знаете, что ?: это такое, это называется Elvis operator , вы можете подробнее прочитать об этом в Kotlin docs . В основном он выполняет проверку на нуль и устанавливает значение с правой стороны, если левая сторона равна нулю.