Search code examples
javaandroidandroid-fragmentsandroid-textwatcher

How to fix java.lang.ArrayIndexOutOfBoundsException: length=0; index=-1


I need help here. So I've been tinkering with android studio and my app crashes everytime I type something in a textfield using onTextChanged and it prints this error in logcat java.lang.ArrayIndexOutOfBoundsException: length=0; index=-1. How do I fix it? Thanks in advance.

Here's my NotesFragment.java:

package com.example.reminderapp;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.ArrayList;

import static android.R.layout.simple_list_item_1;

public class NotesFragment extends Fragment {
    View view;
    static ArrayList<String> notes = new ArrayList<>();
    static ArrayAdapter<String> arrayAdapter;
    FloatingActionButton fabfrNotes;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(notes.size()==0)
        {
            view = inflater.inflate(R.layout.fragment_notes_empty, container, false);
            fabfrNotes = view.findViewById(R.id.fabNotes);
            fabfrNotes.setOnClickListener(v -> {
                Intent intent= new Intent(getContext(), NoteEditorActivity.class);
                startActivity(intent);
            });
        }
        else
        {
            view = inflater.inflate(R.layout.fragment_notes, container, false);
            ListView listView = view.findViewById(R.id.notesListView);

            arrayAdapter = new ArrayAdapter<>(view.getContext(), simple_list_item_1, notes);

            listView.setAdapter(arrayAdapter);
            listView.setOnItemClickListener((parent, view, i, id) -> {
                Intent intent = new Intent(getContext(), NoteEditorActivity.class);
                intent.putExtra("noteId", i);
                startActivity(intent);
            });
        }
        return view;
    }

}

and here's my NoteEditorAcitivity.java:

package com.example.reminderapp;

import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

import androidx.appcompat.app.AppCompatActivity;

public class NoteEditorActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_note_editor);

        EditText editTextTitle = findViewById(R.id.editTextNoteTitle);
        EditText editTextContent = findViewById(R.id.editTextNoteContent);

        Intent intent = getIntent();
        int noteId = intent.getIntExtra("noteId", -1);
        if(noteId!=-1){
            editTextTitle.setText(NotesFragment.notes.get(noteId));
        }

        editTextTitle.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                NotesFragment.notes.set(noteId, String.valueOf(s));
                NotesFragment.arrayAdapter.notifyDataSetChanged();
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }
}

Here's my logcat:

java.lang.ArrayIndexOutOfBoundsException: length=0; index=-1
        at java.util.ArrayList.set(ArrayList.java:455)
        at com.example.reminderapp.NoteEditorActivity$1.onTextChanged(NoteEditorActivity.java:36)
        at android.widget.TextView.sendOnTextChanged(TextView.java:10578)
        at android.widget.TextView.handleTextChanged(TextView.java:10685)
        at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:13568)
        at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:1267)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:576)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:507)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:37)
        at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:228)
        at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:141)
        at android.widget.TextView.doKeyDown(TextView.java:8466)
        at android.widget.TextView.onKeyDown(TextView.java:8240)
        at android.view.KeyEvent.dispatch(KeyEvent.java:2842)
        at android.view.View.dispatchKeyEvent(View.java:14247)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1959)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1959)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1959)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1959)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1959)
        at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1959)
        at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:476)
        at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1861)
        at android.app.Activity.dispatchKeyEvent(Activity.java:4085)
        at androidx.core.app.ComponentActivity.superDispatchKeyEvent(ComponentActivity.java:122)
        at androidx.core.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:84)
        at androidx.core.app.ComponentActivity.dispatchKeyEvent(ComponentActivity.java:140)
        at androidx.appcompat.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:569)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
        at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:3054)
        at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:390)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5947)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5815)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5310)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5485)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5341)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5542)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5314)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5341)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5314)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5518)
        at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:5676)
        at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:3179)
        at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2721)
2021-03-02 15:49:39.538 17484-17484/com.example.reminderapp E/AndroidRuntime:     at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2712)
        at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:3156)
        at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:143)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:335)
        at android.os.Looper.loop(Looper.java:183)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Solution

  • You can get Exception ArrayIndexOutOfBoundsException when you are trying to access an item at index that doesn't exist. Let's say you have array of 10 elements with indexs from 0 to 9. If you try to access the 11th index or more you will get ArrayIndexOutOfBoundsException.

    NotesFragment.notes.set(noteId, String.valueOf(s)); NotesFragment.arrayAdapter.notifyDataSetChanged();

    The first line above is trying to update an item in array at index noteId, you are getting this error because no item exits at that index.

    Please make sure that item exist at index noteId, you can add a break point there and inspect the value of noteId