java.lang.IndexOutOfBoundsException: setSpan ( 0...x ) ends beyond length X

1,可能是EditText,setSelection(x)时超过了 输入框内容的实际长度导致的。

2,手机开启“拼写检查功能”,EditText设置了最大长度,选择提示的某一项文案时超过设置的最大长度限制,导致崩溃。

针对情况2 开启“拼写检查功能” 的举例:

例如,通过InputFilter 或者maxLength 设置了EditText的最大长度为8。

↑ 此时已经输入了7位

↑ 再输入一个空格,此时已经达到最大长度8。

但已经输入的字符有红色横线,显示可以进行提示,点击已输入的字符就会展示下方样式。

此时如果选择“Que tak”是没问题的,因为没有达到最大长度限制。
但选择“quest nak”就会崩溃,报IndexOutOfBoundsException。。


解决办法:
给对应的editText 设置 :setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS)。

-------------------------------------------------------------------------------------------------------------------------------

原因:
参考原文:java.lang.IndexOutOfBoundsException: setSpan ( ... ) ends beyond length 剖析

看trackstack的信息,应该是点击其中一项候选词的时候发生的奔溃。让我们先看看SuggesttionsPopupWindow在处理点击事件的时候做了什么。

@Override
 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
     SuggestionInfo suggestionInfo = mSuggestionInfos[position];
     replaceWithSuggestion(suggestionInfo);
     hideWithCleanUp();
}

代码很简洁,我们继续看看replaceWithSuggestion这个方法,代码挺长的,只保留重点

private void replaceWithSuggestion(@NonNull final SuggestionInfo suggestionInfo) {
    ···
    //suggestion是点击选中的候选词
	final String suggestion = suggestionInfo.mText.subSequence(
		suggestionStart, suggestionEnd).toString();
	//替换
	mTextView.replaceText_internal(spanStart, spanEnd, suggestion);

	//把被替换的词放到候选词列表
	String[] suggestions = targetSuggestionSpan.getSuggestions();
	suggestions[suggestionInfo.mSuggestionIndex] = originalText;

	// Restore previous SuggestionSpans
	//候选词和被替换词的长度差值
	final int lengthDelta = suggestion.length() - (spanEnd - spanStart);
	for (int i = 0; i < length; i++) {
	// Only spans that include the modified region make sense after replacement
	// Spans partially included in the replaced region are removed, there is no
	// way to assign them a valid range after replacement
		if (suggestionSpansStarts[i] <= spanStart && suggestionSpansEnds[i] >= spanEnd) {
			//这里在计算setSpan_internal的时候end加上了候选词和被替换词的长度差值,其实就是默认
			//候选词替换后可以完全显示,假如我们设置了长度限制,例如maxlength,就会引发上述的奔溃
			mTextView.setSpan_internal(suggestionSpans[i], suggestionSpansStarts[i],
			suggestionSpansEnds[i] + lengthDelta, suggestionSpansFlags[i]);
		}
	}
	// Move cursor at the end of the replaced word
	final int newCursorPosition = spanEnd + lengthDelta;
	//这里也有同样的问题
	mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
}

另:

拼写检查的设置位置:

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值