首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >克隆SpannableStringBuilder

克隆SpannableStringBuilder
EN

Stack Overflow用户
提问于 2014-07-17 22:47:12
回答 2查看 1K关注 0票数 6

我正在从事一项活动,在该活动中,我将解析带有标记字符的文本。我正在做的是将它们转换为几种类型的ClickableSpans。

问题是,我需要实现一个函数(让我们称它为函数B),它意味着有重叠的ClickableSpans,这会导致几个问题。

所以我现在要做的是在检测重叠范围的同时创建一个新的SSB,并删除这个特定函数不需要的部分。工作得很好。

但是,我需要能够回到以前的SSB,这似乎不起作用。

一步步地:

代码语言:javascript
复制
// 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“。如下所示:

代码语言:javascript
复制
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的自定义类。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-17 23:03:40

这里的问题是您对valueOf()的使用。它不像你想的那样。它所做的就是返回传入的对象(如果是SpannableStringBuilder);否则,它会将给定的CharSequence封装在SpannableStringBuilder中。来文提交人:

代码语言:javascript
复制
public static SpannableStringBuilder valueOf(CharSequence source) {
    if (source instanceof SpannableStringBuilder) {
        return (SpannableStringBuilder) source;
    } else {
        return new SpannableStringBuilder(source);
    }
}

因此,本质上:

代码语言:javascript
复制
ssb == SpannableStringBuilder.valueOf(ssb);

它们是同一个物体。SpannableStringBuilder不实现Cloneable,因此除了只生成两个副本之外,没有什么简单的方法可以创建副本,例如:

代码语言:javascript
复制
ssb = addClickablePart(chapterTextStr, markupCharactersArray);
ssbCopy = addClickablePart(chapterTextStr, markupCharactersArray);
票数 4
EN

Stack Overflow用户

发布于 2017-04-17 17:15:40

SpannableStringBuilder中的方法子序列复制跨范围。您可以通过调用ssb.subsequence(0, ssb.length)来复制ssb。

代码语言:javascript
复制
SpannableStringBuilder ssbCopy = (SpannableStringBuilder)ssb.subSequence(0, ssb.length());
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24814758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档