2014-01-05 57 views
19

假設你有以下字符串:用的String.format結合Spannable()

String s = "The cold hand reaches for the %1$s %2$s Ellesse's"; 
String old = "old"; 
String tan = "tan"; 
String formatted = String.format(s,old,tan); //"The cold hand reaches for the old tan Ellesse's" 

假設你想用這個字符串結束了,但也有通過String.format取代任何文字特定Span集。

舉例來說,我們也想做到以下幾點:

Spannable spannable = new SpannableString(formatted); 
spannable.setSpan(new StrikethroughSpan(), oldStart, oldStart+old.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
spannable.setSpan(new ForegroundColorSpan(Color.BLUE), tanStart, tanStart+tan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

是否有結識的oldtan開始指數的強勁呢?

請注意,只要搜索「舊」,就會在「冷」中返回「舊」,這樣就不會起作用。

什麼的工作,我想,正在尋找%[0-9]$s事前,並計算抵消在String.format佔了替代品。這似乎是一個頭痛,但我懷疑可能有一種方法,如String.format,它是格式化的更多信息。那麼,在那裏?

+0

至少對於顏色,您可以嘗試替換字符串' tan'並使用spannable = Html.fromHtml(格式化)。 ''不渲染,但。 – Maarten

+2

這幾乎肯定可以使用[TextUtils.expandTemplate](https://developer.android.com/reference/android/text/TextUtils.html#expandTemplate(java.lang.CharSequence,%20java.lang.CharSequence ... ))。 –

回答

11

像使用Spannables是頭疼 - 這大概是最簡單的方法:

String s = "The cold hand reaches for the %1$s %2$s Ellesse's"; 
String old = "<font color=\"blue\">old</font>"; 
String tan = "<strike>tan</strike>"; 
String formatted = String.format(s,old,tan); //The cold hand reaches for the <font color="blue">old</font> <strike>tan</strike> Ellesse's 

Spannable spannable = Html.fromHtml(formatted); 

問題:這不放在一個StrikethroughSpan。爲了製作StrikethroughSpan,我們從this question借用定製TagHandler

Spannable spannable = Html.fromHtml(text,null,new MyHtmlTagHandler()); 

MyTagHandler:

public class MyHtmlTagHandler implements Html.TagHandler { 
    public void handleTag(boolean opening, String tag, Editable output, 
          XMLReader xmlReader) { 
     if (tag.equalsIgnoreCase("strike") || tag.equals("s")) { 
      processStrike(opening, output); 
     } 
    } 
    private void processStrike(boolean opening, Editable output) { 
     int len = output.length(); 
     if (opening) { 
      output.setSpan(new StrikethroughSpan(), len, len, Spannable.SPAN_MARK_MARK); 
     } else { 
      Object obj = getLast(output, StrikethroughSpan.class); 
      int where = output.getSpanStart(obj); 
      output.removeSpan(obj); 
      if (where != len) { 
       output.setSpan(new StrikethroughSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
      } 
     } 
    } 

    private Object getLast(Editable text, Class kind) { 
     Object[] objs = text.getSpans(0, text.length(), kind); 
     if (objs.length == 0) { 
      return null; 
     } else { 
      for (int i = objs.length; i > 0; i--) { 
       if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) { 
        return objs[i - 1]; 
       } 
      } 
      return null; 
     } 
    } 
} 
11

我創建a version of String.format與spannables工作。下載並像普通版一樣使用它。在你的情況下,你會把這些跨度放在格式說明符的周圍(可能使用strings.xml)。在輸出中,它們將圍繞那些指定者被替換的地方。

+0

我試過它只有一個參數索引1(%1 $ s),就像在Android開發者的例子,但我的應用程序崩潰,所以我改變它爲0,它的工作。 所以有一點不一致。 http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling – SnapDragon

+2

@SnapDragon我剛推出了一個修補程序的新提交。感謝您發現錯誤。 –