You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin加速度计算APP解决NumberFormatException问题

Fixing NumberFormatException for Your Acceleration Calculator App

Hey there! Let's sort out that NumberFormatException issue you're hitting. The problem comes from trying to parse empty strings or incomplete number formats directly to Double without any checks. Here's a complete, fixed solution with clear explanations:

Step 1: Cleaned-Up Layout XML

Your original layout works fine—here's the properly formatted version for reference:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/v1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/initial_velocity"
        android:inputType="numberSigned|numberDecimal"
        android:textColor="#F8F5F5"
        android:textColorHint="#FFFFFF"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/v2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/final_velocity"
        android:inputType="numberSigned|numberDecimal"
        android:textColor="#FFFFFF"
        android:textColorHint="#FFFFFF"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/v1" />

    <EditText
        android:id="@+id/s"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/time"
        android:inputType="numberSigned|numberDecimal"
        android:textColor="#FFFFFF"
        android:textColorHint="#FAF6F6"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/v2" />

    <Button
        android:id="@+id/acceleration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:background="#FFFFFF"
        android:text="@string/acceleration1"
        android:textColor="#070707"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/s" />

    <TextView
        android:id="@+id/n"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FFFFFF"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/s1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="@string/ms"
        android:textColor="#EDECEC"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/n" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:text="@string/_2g"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/s1" />

</androidx.constraintlayout.widget.ConstraintLayout>

Step 2: Fixed Kotlin Activity Code

Here's the corrected logic that handles empty inputs and invalid formats gracefully:

import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Get references to all UI elements
        val initialVelocityEt: EditText = findViewById(R.id.v1)
        val finalVelocityEt: EditText = findViewById(R.id.v2)
        val timeEt: EditText = findViewById(R.id.s)
        val resultTv: TextView = findViewById(R.id.n)
        val calculateBtn: Button = findViewById(R.id.acceleration)

        calculateBtn.setOnClickListener {
            // Trim whitespace from inputs to handle accidental spaces
            val initialVelStr = initialVelocityEt.text.toString().trim()
            val finalVelStr = finalVelocityEt.text.toString().trim()
            val timeStr = timeEt.text.toString().trim()

            // Safely convert strings to Double (returns null if invalid)
            val initialVel = initialVelStr.toDoubleOrNull()
            val finalVel = finalVelStr.toDoubleOrNull()
            val time = timeStr.toDoubleOrNull()

            when {
                // Handle invalid initial velocity
                initialVel == null -> {
                    initialVelocityEt.error = "Enter valid initial velocity"
                    Toast.makeText(this, "Invalid initial velocity", Toast.LENGTH_SHORT).show()
                }
                // Handle invalid final velocity
                finalVel == null -> {
                    finalVelocityEt.error = "Enter valid final velocity"
                    Toast.makeText(this, "Invalid final velocity", Toast.LENGTH_SHORT).show()
                }
                // Handle invalid or zero time (prevents division by zero)
                time == null || time == 0.0 -> {
                    timeEt.error = "Enter valid non-zero time"
                    Toast.makeText(this, "Time can't be zero or invalid", Toast.LENGTH_SHORT).show()
                }
                // All inputs are valid—calculate acceleration
                else -> {
                    val acceleration = (finalVel - initialVel) / time
                    resultTv.text = acceleration.toString()
                    Toast.makeText(this, "Acceleration calculated!", Toast.LENGTH_LONG).show()

                    // Clear any previous error messages
                    initialVelocityEt.error = null
                    finalVelocityEt.error = null
                    timeEt.error = null
                }
            }
        }
    }
}

Key Fixes & Explanations

  • Safe Conversion: Replaced toDouble() with toDoubleOrNull()—this returns null instead of throwing an exception if the string can't be parsed (like empty strings, just ".", or non-numeric text).
  • Input Validation: We check each input individually, showing a clear error directly on the problematic EditText plus a Toast for extra clarity. We also add a check for zero time to avoid division-by-zero crashes.
  • Clean Logic: The when statement makes error handling straightforward, ensuring calculations only run when all inputs are valid.
  • Readability: Renamed invalid variable names (like Int, which is a Kotlin keyword) to meaningful names, and trimmed input whitespace to handle accidental spaces.

This solution will stop those NumberFormatException crashes and give your users clear feedback when they enter invalid data.

内容的提问来源于stack exchange,提问作者Margaret Abugewa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:08:11