Android 如何合并一些可扩展对象?

Android 如何合并一些可扩展对象?,android,spannable,charsequence,Android,Spannable,Charsequence,我把一个可扩展对象分成3部分,做不同的操作,然后我需要合并它们 Spannable str = editText.getText(); Spannable selectionSpannable = new SpannableStringBuilder(str, selectionStart, selectionEnd); Spannable endOfModifiedSpannable = new SpannableStringBuilder(str, selectionEnd, editTex

我把一个可扩展对象分成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);            
我怎么做?我还没有找到执行此操作所需的方法或构造函数。

您可以使用以下方法:

TextUtils.concat(span1, span2);

谢谢,它很管用。我注意到我甚至可以合并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) }
}
TextUtils.concat(*yourListOfText.map { it.cloneWithSpans() }.toTypedArray())
fun Iterable.joinToSpannedString(分隔符:CharSequence=“,”,前缀:CharSequence=“”,后缀:CharSequence=“”,限制:Int=-1,截断:CharSequence=“…”,转换:((T)->CharSequence)?=null):跨距字符串{
返回joinTo(SpannableStringBuilder(),分隔符,前缀,后缀,限制,截断,转换)
.让{跨越(它)}
}

希望它可能会对某些人有所帮助。

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

一种解决方法是将
字符序列
写入
包裹
,然后将其读回。执行此操作的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
}
此代码的示例用法:

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) }
}
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

如果您查看方法签名,它需要CharSequence。。。这意味着它将合并你给它的任何数量。效果很好!谢谢有时,Java使事情变得简单,但不太常见。我喜欢那些时光+1@Madbreaks这与Java无关,但与Android API有关。它也可以在C++中容易实现。在我的例子中,这个方法有一些问题:<代码>文本tux.CONTAT(Snp1,“”,Snp2);span1的代码>样式(即span)消失了,只剩下它的字符串表示形式。将“”包装到span中没有任何帮助。同样的事情在这里第一个spannable失去了样式,只有第二个保持了它的样式!如果您的第一个span样式消失,可能是因为您在两个span上使用了相同的
StyleSpan
。您需要为每个span创建一个新的
样式span
。(见附件)