Combining Spannable with String.format()

前端 未结 5 467
刺人心
刺人心 2021-01-31 09:28

Suppose you have the following string:

String s = \"The cold hand reaches for the %1$s %2$s Ellesse\'s\";
String old = \"old\"; 
String tan = \"tan\"; 
String fo         


        
5条回答
  •  一生所求
    2021-01-31 09:49

    Using Spannables like that is a headache -- this is probably the most straightforward way around:

    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
    
    Spannable spannable = Html.fromHtml(formatted);
    

    Problem: this does not put in a StrikethroughSpan. To make the StrikethroughSpan, we borrow a custom TagHandler from this question.

    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;
            }
        }
    }
    

提交回复
热议问题