Search code examples
javaandroidstringindexoutofboundsexceptionclickablespan

A ClickableSpan on a String not text


Ok I have a ClickableSpan (on a TextView called SpecialTextView) that is working perfectly, it contains a String of text (called specialtappedtext). When another ClickableSpan on a different TextView (called BottomTextView) is longclicked it addsthe clicked word to SpecialTextView like this -

specialtappedtext = BottomTextView.getText().toString().substring(startSelection, endSelection);
SpecialTextView.append(" " + specialtappedtext);

The result is SpecialTextView displays whatever words the user taps. All good so far, but I'm then allowing the user to longclick a word in SpecialTextView to then remove it. I get a String (called wordtobedeleted) from what the user taps on in SpecialTextView and then a String (called fullspecialtext) which is the full line of text as it appears in SpecialTextView. I then replace any instance of wordtobedeleted that appears in fullspecialtext and display the result back in SpecialTextView like this -

wordtobedeleted = SpecialTextView.getText().toString().substring(startSelection, endSelection);
resultspecialtext = fullspecialtext.replace(wordtobedeleted, " ");
SpecialTextView.setText(" " + resultspecialtext);

So if the user taps the words "Bandit is in the living room" as displayed in BottomTextView then SpecialTextView will display them in that order tapped. Pressing any of these words in the SpecialTextView should remove them, so if I tap the words "is", "the" and "living" the SpecialTextView will display "Bandit in room" but instead I get a crash. It's seems that I can't get a substring from a textview that contains a string, if I'm reading this right as when I comment out code the part that causes the crash is where I get the String wordtobedeleted from SpecialTextView.

The ClickableSpan, sorry about some of the long winded names it helps me to at a glance keep track of what's what because I'm juggling another ClickableSpan with almost identical names etc. -

 SpecialTextView.setMovementMethod(LinkMovementMethod.getInstance());
 SpecialTextView.setText(specialtappedtext, TextView.BufferType.SPANNABLE);
 Spannable specialspans = (Spannable) SpecialTextView.getText();
 BreakIterator specialiterator = BreakIterator.getWordInstance(Locale.UK);
 specialiterator.setText(specialtappedtext);
 int specialstart = specialiterator.first();
 for (int specialend = specialiterator.next(); specialend != BreakIterator.DONE; specialstart = specialend, specialend = specialiterator
            .next()) {
     String specpossibleWord = specialtappedtext.substring(specialstart, specialend);
     if (Character.isLetterOrDigit(specpossibleWord.charAt(0))) {
            ClickableSpan specialclickSpan = getSpecialClickableSpan(specpossibleWord);
         specialspans.setSpan(specialclickSpan, specialstart, specialend,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
     }
 }

Whether it helps or not, but here's the error log thing -

 Process: com.example.warrenanna.game003, PID: 18321
                                                                            java.lang.StringIndexOutOfBoundsException: length=30; index=-1
                                                                                at java.lang.String.substring(String.java:1926)
                                                                                at com.example.warrenanna.game003.MainActivity$2.onLongClick(MainActivity.java:133)
                                                                                at android.view.View.performLongClickInternal(View.java:5762)
                                                                                at android.view.View.performLongClick(View.java:5720)
                                                                                at android.widget.TextView.performLongClick(TextView.java:9427)
                                                                                at android.view.View.performLongClick(View.java:5738)
                                                                                at android.view.View$CheckForLongPress.run(View.java:22450)
                                                                                at android.os.Handler.handleCallback(Handler.java:751)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                at android.os.Looper.loop(Looper.java:241)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:6281)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

I'm new to anything this advanced in programming and I don't really know my way around ClickableSpan so I'm kind of winging it but was doing fine until now!


Solution

  • you problem is

    java.lang.StringIndexOutOfBoundsException: length=30; index=-1

    • Check wordtobedeleted = SpecialTextView.getText().toString().substring(startSelection, endSelection); in your code .

    startSelection and endSelection are possible equal to -1 .

    • Check String specpossibleWord = specialtappedtext.substring(specialstart, specialend); in your code .

    specialstart and specialend are possible equal to -1.