Search code examples
androidxmlkotlinandroid-edittextsettext

Setting text in EditText with input type number


I am using a TextEdit that only accepts numbers as input type and I would like to set the value of the TextEdit when a button is pressed. However, I can't get this to work.

When I just do textWithAmount.setText(balance), with balance being a long, I get a squiggly line saying that this doesn't conform the setText function and I can't run my code.

When I cast it to Int (setText(balance.toInt()), I get the following error:

android.content.res.Resources$NotFoundException: String resource ID #0x2710

When I cast it to String (setText(balance.toString()), I get the following error:

java.lang.ClassCastException: android.text.SpannableStringBuilder cannot be cast to java.lang.Long

Kotlin Code:

val buttonAll = findViewById<Button>(R.id.buttonWithAll)
var balance : Long = 0
buttonAll.setOnClickListener{
                textAmount.setText(balance.toInt())
            }

XML:

<EditText
        android:id="@+id/textWithAmount"
        android:layout_width="228dp"
        android:layout_height="68dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="10dp"
        android:ems="100"
        android:importantForAutofill="no"
        android:inputType="number"
        app:layout_constraintEnd_toStartOf="@+id/buttonWithAll"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView4" />

    <Button
        android:id="@+id/buttonWithAll"
        android:layout_width="68dp"
        android:layout_height="68dp"
        android:layout_marginEnd="9dp"
        android:text="@string/all"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/textWithAmount"
        app:layout_constraintTop_toTopOf="@+id/textWithAmount" />

Does anyone know a solution to this? Any answers would be appreciated

Edit: I just realized I also have a textChangedListener on the same TextEdit which is probably called when I fill it. Maybe something is wrong there:

textAmount.addTextChangedListener { text ->
                    val input : Long = text as Long
                    if(input > cash){
                        textAmount.setText(cash.toString())
                    }
                }```

Solution

  • setText(balance.toString()) is correct. Your error is in the code you posted in your comment.

    The java.lang.ClassCastException is because you are casting something that is not a Long to a Long. I think maybe you need clarification on the difference between converting something and casting something. Casting (using the as keyword) does not convert one type of object into another. Casting is you telling the compiler that the object already is that other type of object.

    When you cast, the compiler takes your word for it that you know better than the compiler, and it allows you to treat it like that other type of object. Then at runtime, if your declaration to the compiler was incorrect, it will crash with a ClassCastException.

    For those reasons, you should rarely be using as at all. It is for special cases, like if you had a List<Any> and you want to pull something out of it and treat it as a more specific class. Or when you are writing a class that works with generics and run into a situation where the compiler cannot figure out a type. Or when the object implements multiple interfaces and there is ambiguity about which function overload you want to pass it to.

    When you get text from a TextView, it is some kind of CharSequence object, specifically a SpannableStringBuilder. If you want to use it as a Long, you must convert to a Long, not cast to a Long. You should also account for the fact that the existing content passed to your listener may not be a non-null text that can truly be converted to a Long. For that, you can do something like using the Elvis operator to set a default value if the text cannot be converted.

    textAmount.addTextChangedListener { text ->
        val input : Long = text?.toString()?.toLongOrNull() ?: 0L
        if(input > cash){                         
            textAmount.setText(cash.toString())
        }
    }