如何合并一些可跨越的对象?

我把一个可跨越的对象分成3个部分,做不同的操作,然后我需要合并它们。

Spannable str = editText.getText();
Spannable selectionSpannable = new SpannableStringBuilder(str, selectionStart, selectionEnd);
Spannable endOfModifiedSpannable = new SpannableStringBuilder(str, selectionEnd, editText.getText().length());
Spannable beginningOfModifiedSpannable = new SpannableStringBuilder(str, 0, selectionStart);

我怎么能做到呢? 我还没有找到所需的方法或构造函数来做到这一点。

29802 次浏览

谢谢,它工作了。我注意到我甚至可以合并3个可跨越的对象:

(Spanned) TextUtils.concat(foo, bar, baz)

我知道这很老了,但是在修改了一下 kotlin stdlib 之后,我得到了这段代码:

fun <T> Iterable<T>.joinToSpannedString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): SpannedString {
return joinTo(SpannableStringBuilder(), separator, prefix, postfix, limit, truncated, transform)
.let { SpannedString(it) }
}

希望能帮到别人。

正如 marwinXXII 在评论中所说,使用 TextUtils.concat确实有效,但是在某些情况下,当您在单个 CharSequence中有多个同一跨度的实例时,可能会导致样式丢失。

变通方法可以是将 CharSequence写入 Parcel,然后再读回来。下面是执行此操作的 Kotlin 扩展代码示例:

fun CharSequence.cloneWithSpans(): CharSequence {
val parcel = Parcel.obtain()
TextUtils.writeToParcel(this, parcel, 0)
parcel.setDataPosition(0)
val out = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel)
parcel.recycle()
return out
}

此代码的用法示例:

TextUtils.concat(*yourListOfText.map { it.cloneWithSpans() }.toTypedArray())

现在,您可以连接大量的 CharSequences,而不用担心丢失任何样式和格式!

请注意,这将工作的 大部分样式,它不工作的所有时间,但应该足以涵盖所有的基本样式。

使用 SpannableStringBuilder

更妙的是——让 kotlin 操作员超负荷工作:

operator fun Spannable.plus(other: Spannable): Spannable{
return SpannableStringBuilder(this).append(other)
}

把它作为顶级函数放到任何一个 kotlin 文件中。

你可以用 +连接:

val spanA = ...
val spanB = ...


val concatenatedSpan = spanA + spanB