Search code examples
androidkotlinmutablelist

MutableLIst Error in OnTextChangedListener


A feature of my app allows the user to update an element of their exercise by just typing in an Edittext. In the background, I use a TextWatcher to listen for changes and save each change to the mutableList that is popualted when the UI opens. It works fine with a mutableList of more than 1 element. But it returns an error when there's only one element.

Is there an issue with how I Use the MutableList?

I input the data into the arraylist here

dialogViewModel.clickedExercise(this, exerciseID) {repList = it.numberOfReps.split(", ") as MutableList<String> ...}

I then create an Edittext for each of the elements.

                editTextReps.apply {
                    setText(reps)
                    //textAlignment = View.TEXT_ALIGNMENT_CENTER
                    textSize = 20f
                    id = repInt
                    setBackgroundColor(WHITE)
                    setPadding(0, 0, 16, 0)
                    layoutParams = ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT
                    )...}

I Then Listen for the change in each EditText

editTextReps.addTextChangedListener(object : TextWatcher {
                    override fun afterTextChanged(p0: Editable?) {
                        exercise.numberOfReps = repString.toString()
                        if (repTrial == repString.toString())
                            Log.d(TAG, "Nothing Change")
                        else
                            Log.d(TAG, "It changed")
                        dialogViewModel.update(exercise)
                        Log.d(TAG, repString.toString())
                        repString.clear()
                    }

                    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                    }

                    override fun onTextChanged(
                        exerciseString: CharSequence?,
                        p1: Int,
                        p2: Int,
                        p3: Int
                    ) {
                        //repList[listPosition]

                        //TODO: Position probably not right, error occurs when attempt is made to modify single set
                        Log.d(TAG, "${repList.size} , ${repList[listPosition]},\n$repTrial")
                        val testString = exerciseString.toString()
                        Log.d(TAG, "test: $testString")
                      
               this is the issue -> -> -> ->repList[listPosition] = testString
                      


  Log.d(TAG, "List Position: $listPosition, ${repList[listPosition]}")
                        for (rep in repList) {
                            repString.append("$rep, ")
                            Log.d(TAG, "${repList.size}")
                        }
                    }
                })

This code works fine with more than one item, but it crashes when the MutableList only contains One item

Error Readout

E/InputEventReceiver: Exception dispatching input event.
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI: java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)
        at com.homeofficeprojects.countmyreps.DialogUpdateExercise$onCreate$1$5.onTextChanged(DialogUpdateExercise.kt:195)
        at android.widget.TextView.sendOnTextChanged(TextView.java:9754)
        at android.widget.TextView.handleTextChanged(TextView.java:9851)
        at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:12509)
        at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:1263)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:575)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:229)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:36)
        at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:370)
        at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:71)
        at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:479)
        at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:362)
        at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:141)
        at android.widget.TextView.doKeyDown(TextView.java:7665)
        at android.widget.TextView.onKeyDown(TextView.java:7442)
        at android.view.KeyEvent.dispatch(KeyEvent.java:2692)
        at android.view.View.dispatchKeyEvent(View.java:12450)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.widget.ScrollView.dispatchKeyEvent(ScrollView.java:389)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:428)
        at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1820)
        at android.app.Dialog.dispatchKeyEvent(Dialog.java:811)
        at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:342)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5037)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4905)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4585)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4585)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$InputStage.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.homeofficeprojects.countmyreps, PID: 10507
    java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)
        at com.homeofficeprojects.countmyreps.DialogUpdateExercise$onCreate$1$5.onTextChanged(DialogUpdateExercise.kt:195)
        at android.widget.TextView.sendOnTextChanged(TextView.java:9754)
        at android.widget.TextView.handleTextChanged(TextView.java:9851)
        at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:12509)
        at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:1263)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:575)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:229)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:36)
        at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:370)
        at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:71)
        at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:479)
        at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:362)
        at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:141)
        at android.widget.TextView.doKeyDown(TextView.java:7665)
        at android.widget.TextView.onKeyDown(TextView.java:7442)
        at android.view.KeyEvent.dispatch(KeyEvent.java:2692)
        at android.view.View.dispatchKeyEvent(View.java:12450)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.widget.ScrollView.dispatchKeyEvent(ScrollView.java:389)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1896)
        at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:428)
        at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1820)
        at android.app.Dialog.dispatchKeyEvent(Dialog.java:811)
        at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:342)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5037)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4905)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4585)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4585)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4479)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4445)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4585)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4453)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4426)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7092)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7061)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7022)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7195)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:326)
        at android.os.Looper.loop(Looper.java:160)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Solution

  • About the split(delimiter) method - If the delimiter does not occur anywhere in the input, the resulting list has just one element containing the original input. So, in this case output list is immutable (SingletonList) and add operation is not supported (it throws UnsupportedOperationException).

    To get a mutable list, you can use the toMutableList() method:

    repList = it.numberOfReps.split(", ").toMutableList()