我正在从事一个 Activity ,其中我解析带有标记字符的文本。
我正在做的就是将它们转换为多种类型的ClickableSpans。

问题是我需要实现一个函数(让我们将其称为函数B),该函数暗示具有重叠的ClickableSpans并导致多个问题。

因此,我现在要做的是在检测重叠范围的同时创建一个新的SSB,并删除该特定功能不需要的范围。工作正常。

但是,我需要能够返回到上一个SSB,但这似乎不起作用。

一步步:

// I CREATE THE SSBs
...
static SpannableStringBuilder ssb;
static SpannableStringBuilder ssbCopy;

// I IMPLEMENT MY CUSTOM FUNCTION THAT PARSES THE TEXT AND SETS THE SBB AS A TEXTVIEW CONTENT
...
textView.setMovementMethod(new LinkTouchMovementMethod());
ssb = addClickablePart(chapterTextStr, markupCharactersArray);
textView.setText(ssb);

// WHEN A BUTTON IS CLICKED I IMPLEMENT MY FUNCTION B. WHERE I CREATE A COPY OF MY ORIGINAL SSB AND STORE IT IN ssbCopy, AND SET IT AS THE TEXTVIEW CONTENT
...
ssbCopy = SpannableStringBuilder.valueOf(ssb);

// I REMOVE THE OVERLAPPING SPANS
...
overlapSpans = ssbCopy.getSpans(index, index+word.length(), TouchableSpan.class);

for (int c=0;c<overlapSpans.length;c++) {
    ssbCopy.removeSpan(overlapSpans[c]);
}

// I SET THE NEW CLICKABLE SPANS
...
ssbCopy.setSpan(touchableSpan, index, index + word.length(), 0);

// AND SET THE NEW SSB CONTENT TO THE TEXTVIEW
textView.setText(ssbCopy);

// EVERYTHING WORKS FINE UP TO HERE
// BUT WHEN I TRY TO SET BACK THE ORIGINAL SSB BACK AS THE CONTENT OF MY TEXTVIEW WHEN THE USER CLICKS A BUTTON
...
textView.setText(ssb);

// THE ORIGINAL SSB IS EXACTLY LIKE THE COPY (ssbCopy) AND CONTAINS THE SAME CLICKABLE SPANS I ADDED. NOT ONLY THE ORIGINAL ONES

我想这听起来有些困惑,我不确定我是否解释正确,但是我无法解决这个问题。

编辑:

按照kcoppock的答案,我知道不可能克隆ssb,而valueOf(ssb)只是对象的副本。
因此,我最终通过遍历所有元素并将其应用于新的ssb来手动克隆我的“ssb”。像这样:
TouchableSpan[] spans = ssb.getSpans(0, ssb.length(), TouchableSpan.class);

ssbCopy = new SpannableStringBuilder(chapterTextStr+"dsadsa");

for (int c=0;c<spans.length;c++) {
    TouchableSpan obj = spans[c];

    ssbCopy.setSpan(obj, ssb.getSpanStart(obj), ssb.getSpanEnd(obj), 0);
}

顺便说一句,TouchableSpan是我创建的自定义类,它扩展了ClickableSpan

最佳答案

这里的问题是您对valueOf()的使用。它没有按照您的想法做。它所做的就是返回传入的对象(如果它是SpannableStringBuilder);否则,它将给定的CharSequence包装在SpannableStringBuilder中。从来源:

public static SpannableStringBuilder valueOf(CharSequence source) {
    if (source instanceof SpannableStringBuilder) {
        return (SpannableStringBuilder) source;
    } else {
        return new SpannableStringBuilder(source);
    }
}

所以本质上:
ssb == SpannableStringBuilder.valueOf(ssb);

它们是同一对象。 SpannableStringBuilder没有实现Cloneable,因此没有简单的方法来制作副本,除了仅生成两个副本外,例如:
ssb = addClickablePart(chapterTextStr, markupCharactersArray);
ssbCopy = addClickablePart(chapterTextStr, markupCharactersArray);

10-05 18:16