Reputation: 275
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
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