pepperlove
pepperlove

Reputation: 275

IndexOutOfBoundsException for EditText setSelection Android

The Fragments crashes when trying to get the data using the location with the error below:

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$1.onChanged(RepresentativeFragment.kt:119)
        at com.example.android.politicalpreparedness.representative.RepresentativeFragment$populateStatesInformation$1.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$1.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)

I am confused how this is causing an error. It's supposed to show the value that's in the adapter right? Fragment Code :

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)
    }
}

The XML Code for that text field.

 <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>

Upvotes: 1

Views: 1049

Answers (1)

Tyler V
Tyler V

Reputation: 10920

This error is because setSelection(i) doesn't select item i from the adapter for a AutoCompleteTextView, it attempts to move the cursor to position i in the current text, so if i is greater than the length of the text you get that error.

You can use setSelection(i) with a Spinner, but it has different behavior with an AutoCompleteTextView. To do the equivalent of setSelection in a AutoCompleteTextView, use this instead of the setSelection call:

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

The second argument (false) is necessary for it to operate like a spinner and keep the options around instead of applying a filter.

There is an older, but still useful, thread about this issue here too.

Upvotes: 2

Related Questions