EditText setSelection 的 IndexOutOfBoundsException Android

IndexOutOfBoundsException for EditText setSelection Android

尝试使用以下错误的位置获取数据时片段崩溃:

2022-05-26 00:42:46.057 30678-30678/com.example.android.politicalpreparedness E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.politicalpreparedness, PID: 30678
    java.lang.IndexOutOfBoundsException: setSpan (5 ... 5) ends beyond length 0
        at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1325)
        at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:684)
        at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:676)
        at android.text.Selection.setSelection(Selection.java:96)
        at android.text.Selection.setSelection(Selection.java:78)
        at android.widget.EditText.setSelection(EditText.java:129)
        at com.example.android.politicalpreparedness.representative.RepresentativeFragment$populateStatesInformation.onChanged(RepresentativeFragment.kt:119)
        at com.example.android.politicalpreparedness.representative.RepresentativeFragment$populateStatesInformation.onChanged(RepresentativeFragment.kt:23)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at androidx.lifecycle.LiveData.run(LiveData.java:91)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

我很困惑这是怎么导致错误的。它应该显示适配器中的值,对吗? 片段代码:

private fun populateStatesInformation() {
    val statesArray = requireContext().resources.getStringArray(R.array.states)
    binding.addressState.setAdapter(ArrayAdapter(requireContext(), R.layout.layout_state_list_item, statesArray))

    viewModel.address.observe(viewLifecycleOwner) {
        var index = statesArray.indexOf(it.state)
        if (index == -1) {
            index = 0
        }
        binding.addressState.setSelection(index)
    }
}

该文本字段的 XML 代码。

 <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/address_state_layout"
            style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="4dp"
            android:hint="@string/address_state"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/address_zip_layout"
            app:layout_constraintTop_toTopOf="@id/address_zip_layout">

            <AutoCompleteTextView
                android:id="@+id/address_state"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:editable="false"
                android:ellipsize="end"
                android:maxLines="1"
                tools:ignore="Deprecated,LabelFor" />

        </com.google.android.material.textfield.TextInputLayout>

此错误是因为 setSelection(i) 没有 select 项目 i 来自 AutoCompleteTextView 的适配器,它试图将光标移动到位置 i 在当前文本中,因此如果 i 大于文本的长度,则会出现该错误。

您可以将 setSelection(i) 与 Spinner 一起使用,但它与 AutoCompleteTextView 的行为不同。要在 AutoCompleteTextView 中执行与 setSelection 等效的操作,请使用它代替 setSelection 调用:

binding.addressState.setText(statesArray[index], false)

第二个参数 (false) 对于它像微调器一样运行并保留选项而不是应用过滤器是必需的。

关于这个问题还有一个旧的但仍然有用的线程 here