2012-04-02 27 views
3

原始字符串:的Android TextView的格式多個單詞

的Lorem ##存有## DOLAR ##坐## ATEM。 Lorem ipsum dolar坐## atem ##。

格式化後:

的Lorem #ipsum DOLAR #sit ATEM。 Lorem ipsum dolar坐#atem。

但只有最後一個有我想要的Formating。見下圖。

CODE

private void format() { 
    CharSequence text = editContent.getText(); 

    MovementMethod movementMethod = editContent.getMovementMethod(); 
    if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod)) 
    { 
     editContent.setMovementMethod(LinkMovementMethod.getInstance()); 
    } 

    text = setSpanBetweenTokens(text, "##", new ForegroundColorSpan(0xFF0099FF), new UnderlineSpan(), new ClickableSpan() { 
     @Override 
     public void onClick(View widget) { 
      Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    editContent.setText(text); 
} 

private static CharSequence setSpanBetweenTokens(CharSequence text, String token, CharacterStyle... characterStyle) { 
    int tokenLen = token.length(); 
    int start = text.toString().indexOf(token) + 1; 
    int end = text.toString().indexOf(token, start); 

    while (start > -1 && end > -1) 
    { 
     SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); 
     for (CharacterStyle c : characterStyle) { 
      spannableStringBuilder.setSpan(c, start, end, 0); 
     } 

     spannableStringBuilder.delete(end, end + tokenLen); 
     spannableStringBuilder.delete(start - 1, start); 

     text = spannableStringBuilder; 

     start = text.toString().indexOf(token) + 1; 
     end = text.toString().indexOf(token, start); 
    } 

    return text; 
} 

編輯

我的最終解決方案

private void format() { 
    CharSequence text = editContent.getText(); 

    MovementMethod movementMethod = editContent.getMovementMethod(); 
    if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod)) 
    { 
     editContent.setMovementMethod(LinkMovementMethod.getInstance()); 
    } 

    text = setSpanBetweenTokens(text, "##"); 

    editContent.setText(text); 
} 

private static CharSequence setSpanBetweenTokens(CharSequence text, String token) { 
    int tokenLen = token.length(); 
    int start = text.toString().indexOf(token) + 1; 
    int end = text.toString().indexOf(token, start); 

    while (start > -1 && end > -1) 
    { 
     SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); 

     spannableStringBuilder.setSpan(new ForegroundColorSpan(0xFF0099FF), start, end, 0); 
     spannableStringBuilder.setSpan(new UnderlineSpan(), start, end, 0); 
     spannableStringBuilder.setSpan(new ClickableSpan() { 
      @Override 
      public void onClick(View widget) { 
       Log.d("DEBUG", "Click"); 
      } 
     }, start, end, 0); 

     spannableStringBuilder.delete(end, end + tokenLen); 
     spannableStringBuilder.delete(start - 1, start); 

     text = spannableStringBuilder; 

     start = text.toString().indexOf(token) + 1; 
     end = text.toString().indexOf(token, start); 
    } 

    return text; 
} 

回答

4

傳遞不同的對象爲每個跨度:

spannableStringBuilder.setSpan(c, start, end, 0); 

你傳遞同一個對象的每個跨度:

new ForegroundColorSpan(0xFF0099FF) 

當跨度對象spannableStringBuilder存在,那麼它的變化只是界限,不增加新的跨越。

3

我會建議一個更簡單的方法。如果您的格式需求是基本的,簡單的正則表達式+ Html.fromHtml()應該做的伎倆:

private void format() { 
    String mText = editContent.getText(); 

    Spanned mSpannedText = Html.fromHtml(mText.replaceAll("##(.*?)##)","<font color=\"0xFF0099\">#$1</font>"), 

    editContent.setText(mSpannedText); 
} 
+0

我更新了我的格式函數 – 2012-04-02 10:25:37

+0

我認爲REGEX和WEBVIEWS都是最後一個資源,它們都是資源密集型的,因此對於簡單的事情並不好。 – 2013-12-26 22:09:26

+0

@Jorge Aguilar,我不認爲這個片段創建了一個webview。性能影響可以忽略不計。 – 2013-12-27 09:07:08

1

最終的解決方案正確環路但是你的第一個令牌將不能正確地刪除,因爲你已經使用

int start = text.toString().indexOf(token) + 1; 

只有當您的令牌長度爲1個字符時纔會起作用。既然你選擇的令牌是##更改上面的代碼中,利用已經建立的變量tokenLen

int start = text.toString().indexOf(token) + tokenLen; 

這將確保您的文字是正確編輯您的令牌的所有痕跡都被刪除。

相關問題