2014-07-17 48 views
3

我正在處理一個活動,我在其中解析帶有標記字符的文本。 我正在做的是將它們轉換爲幾種類型的ClickableSpans。克隆SpannableStringBuilder

問題是,我需要實現一個函數(讓我們稱之爲函數B),這意味着有重疊ClickableSpans,並導致幾個問題。

所以我現在正在做的是創建一個新的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

回答

2

的問題是你的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,所以沒有簡單的方法來進行復印時,除了剛纔生成的兩個副本,例如:在SpannableStringBuilder複製跨度

ssb = addClickablePart(chapterTextStr, markupCharactersArray); 
ssbCopy = addClickablePart(chapterTextStr, markupCharactersArray); 
+0

感謝您對關於valueOf()的澄清!至少我知道現在問題所在。但是,我無法實現生成兩個副本解決方案,因爲我需要我的副本在對標記字符進行剝離後對ssb進行更改。將繼續嘗試。任何進一步的想法讚賞 – Cruclax

+0

那麼,我最終克隆了ssb「手動」。你的答案是讓我知道什麼是錯的,所以標記爲正確。 – Cruclax

+0

是的,說實話,這可能是唯一的出路。只需將它放在某個實用程序類中,並稍後保存即可。 :)我想你可以傳入'Object。class'來獲得所有的span類型(如果你最終需要的不僅僅是'TouchableSpan'克隆)。 – kcoppock