问题描述
我使用的 TextEdit 只接受数字作为输入类型,我想在按下按钮时设置 TextEdit 的值。但是,我无法使其正常工作。
当我只执行 textWithAmount.setText(balance) 时,由于 balance 很长,我收到一条波浪线,表示这不符合 setText 函数并且我无法运行我的代码。
当我将其转换为 Int (setText(balance.toInt()) 时,出现以下错误:
android.content.res.Resources$NotFoundException:字符串资源 ID #0x2710
当我将其转换为 String (setText(balance.toString()) 时,出现以下错误:
java.lang.classCastException: android.text.SpannableStringBuilder 无法转换为 java.lang.Long
科特林代码:
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" />
编辑: 我刚刚意识到我在同一个 TextEdit 上也有一个 textChangedListener ,当我填充它时可能会调用它。也许那里出了点问题:
textAmount.addTextChangedListener { text ->
val input : Long = text as Long
if(input > cash){
textAmount.setText(cash.toString())
}
}```
解决方法
实际情况是 balance.toInt()
是一个数字,因此当您使用 setText
时,您正在使用采用数字参数的方法。
setText(@Stringres ...)
由于这只是一个数字而不是在 strings.xml
文件中生成的字符串资源,因此无法找到它并崩溃
试试这个
setText("$balance")
关于文本监听器部分也有一些改进
val input = editable?.toString()?.toLongOrNull() ?: return@addTextChangedListener
那里的 lambda 参数是可空的可编辑的,而不是文本,当将文本解析为任何数字类型时,总是有数字格式异常的机会,例如,空文本。
,setText(balance.toString())
是正确的。您的错误在于您在评论中发布的代码。
java.lang.ClassCastException
是因为您正在将不是 Long 的内容转换为 Long。我想也许您需要澄清转换某些东西和铸造某些东西之间的区别。强制转换(使用 as
关键字)不会将一种类型的对象转换为另一种类型。强制转换是您告诉编译器对象已经是其他类型的对象。
当您进行强制转换时,编译器相信您比编译器更了解它,并允许您将其视为其他类型的对象。然后在运行时,如果你对编译器的声明不正确,它会因 ClassCastException 而崩溃。
出于这些原因,您根本不应该使用 as
。它适用于特殊情况,例如如果您有一个 List<Any>
并且您想从中提取某些内容并将其视为更具体的类。或者,当您编写一个使用泛型的类时,遇到编译器无法确定类型的情况。或者当对象实现了多个接口并且对于要将其传递给哪个函数重载不明确时。
当您从 TextView 获取文本时,它是某种 CharSequence 对象,特别是 SpannableStringBuilder。如果要将其用作 Long,则必须转换为 Long,不能转换为 Long。您还应该考虑这样一个事实,即传递给您的侦听器的现有内容可能不是可以真正转换为 Long 的非空文本。为此,如果文本无法转换,您可以使用 Elvis 运算符来设置默认值。
textAmount.addTextChangedListener { text ->
val input : Long = text?.toString()?.toLongOrNull() ?: 0L
if(input > cash){
textAmount.setText(cash.toString())
}
}