Android自定义组合跨度为spannable字符串

时间:2013-12-27 20:52:14

标签: android spannablestring spannable

我如何创建将不同类型的跨距组合在一起的自定义Spans,例如TypefaceSpan + RelativeSizeSpan。我想创建一个逻辑跨度,如“脚注”或“Header2”,它将改变文本字体和大小。

1 个答案:

答案 0 :(得分:4)

您可以将两个不同的跨度应用于相同的部分。

SpannableStringBuilder builder = new SpannableStringBuilder("Hello there");
builder.setSpan(new TypefaceSpan("arial"), 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new RelativeSizeSpan(1.5f), 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

修改 您说您正在寻找一种方法来创建将这些跨度组合在一起的聚合Spans - 以便实际样式(例如TypefaceSpan或RelativeSizeSpan)可以封装在逻辑跨度内(例如FooterSpan)

由于TypeFaceSpan和RelativeSizeSpan都是MetricEffectingSpan的子代,因此以下可能是一个解决方案:

class FooterSpan extends MetricAffectingSpan {

        MetricAffectingSpan[] spans;

        public FooterSpan(MetricAffectingSpan... spans) {
            this.spans = spans;
        }
        @Override
        public void updateMeasureState(TextPaint p) {
            for(MetricAffectingSpan span : spans) {
                span.updateMeasureState(p);
            }
        }

        @Override
        public void updateDrawState(TextPaint tp) {
            for(MetricAffectingSpan span : spans) {
                span.updateDrawState(tp);
            }
        }
    }

示例用法:

builder.setSpan(new FooterSpan(new TypefaceSpan("arial"), new RelativeSizeSpan(1.5f)), 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

您甚至可以用更专业的方式编写FooterSpan,以便您可以像这样使用它:

builder.setSpan(new FooterSpan("arial", 1.5f), 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

我认为将FooterSpan用于第二种情况是微不足道的。