17

如果我有一个SpannedString(或SpannableString这样的

在此处输入图像描述

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 1, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

我将如何遍历结果的跨度String

4

1 回答 1

33

按顺序遍历跨度

您可以使用来获取 a或getSpans中的跨度数组。但是,仅循环遍历结果并不一定会按顺序将它们提供给您。要按顺序排列它们,您可以使用.SpannedSpannable StringgetSpansnextSpanTransition

这是一个与SpannedString问题中的示例类似的示例。(ASpannableString也一样。)绿线显示跨度转换的位置。文本默认为黑色。

可跨行字符串示例

代码找到下一个跨度转换,然后获取当前范围内的所有跨度。

int next;
for (int i = 0; i < spannableString.length(); i = next) {

    // find the next span transition
    next = spannableString.nextSpanTransition(i, spannedString.length(), CharacterStyle.class);

    // get all spans in this range
    int numOfSpans = 0;
    CharacterStyle[] spans = spannableString.getSpans(i, next, CharacterStyle.class);
    for(int j = 0; j < spans.length; j++) {
        numOfSpans++;
    }

    Log.i("TAG", "spans from " + i + " to " + next + ": " + numOfSpans);
}

输出:

spans from 0 to 1: 0
spans from 1 to 3: 1
spans from 3 to 8: 2
spans from 8 to 11: 1
spans from 11 to 12: 0

感谢此代码的想法。

跨度类型

通常在遍历跨度时,您会选择某种类型的跨度。例如,如果您想删除所有前景色跨度,您可以执行以下操作:

// get spans
ForegroundColorSpan[] spans = spannableString.getSpans(0, spannableString.length(), ForegroundColorSpan.class);

// loop through spans
for (ForegroundColorSpan span : spans) {
    spannableString.removeSpan(span);
}

请注意,这不适用于 a SpannedString,因为 a 中的跨度SpannedString是不可变的(请参阅此答案)。

如果您想获取任何类型的所有跨度,您可以将类型设置为Object.class.

Object[] spans = spannableString.getSpans(0, spannableString.length(), Object.class);

如果您想要影响角色级别外观的所有跨度,您可以使用CharacterStyle.class. 如果在循环中您想进一步将跨度限制在属于 的范围内MetricAffectingSpan,您可以这样做。

CharacterStyle[] spans = spannableString.getSpans(0, spannableString.length(), CharacterStyle.class);
for (CharacterStyle span : spans) {
    if (span instanceof MetricAffectingSpan) {
        // do something
    }
}

这是跨度类型的一般层次结构分解。它可能不完整。阅读Spans,一个强大的概念以获取更多信息。

Object
    CharacterStyle
        BackgroundColorSpan
        ClickableSpan
            URLSpan
        ForegroundColorSpan
        MaskFilterSpan
        StrikethroughSpan
        SuggestionSpan
        UnderlineSpan 
        MetricAffectingSpan
            AbsoluteSizeSpan
            LocaleSpan
            RelativeSizeSpan
            ReplacementSpan
                DynamicDrawableSpan
                    ImageSpan 
            ScaleXSpan
            StyleSpan
            SubscriptSpan
            SuperscriptSpan
            TextAppearanceSpan
            TypefaceSpan 
    ParagraphStyle
        AlignmentSpan
            AlignmentSpan.Standard
        BulletSpan
        DrawableMarginSpan
        IconMarginSpan
        LeadingMarginSpan
            LeadingMarginSpan.LeadingMarginSpan2
            LeadingMarginSpan.Standard
        LineBackgroundSpan
        LineHeightSpan
            LineHeightSpan.WithDensity
        QuoteSpan
        TabStopSpan
            TabStopSpan.Standard
        WrapTogetherSpan
于 2017-04-07T05:49:31.800 回答