如何在Android中的SpannedString或SpannableString中循环遍历 [英] How to loop through the spans in a SpannedString or SpannableString in Android

查看:186
本文介绍了如何在Android中的SpannedString或SpannableString中循环遍历的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有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的跨度?

How would I loop through the spans of the resulting String?

推荐答案

按顺序遍历跨度

您可以使用getSpans来获取SpannedSpannable String中的跨度数组.但是,仅循环遍历getSpans结果将不一定会给出将它们按顺序发送给您.为了使它们井然有序,您可以使用 nextSpanTransition .

Looping through the spans in order

You can use getSpans to get an array of the spans in a Spanned or Spannable String. However, just looping through the getSpans results will not necessarily give them to you in order. To get them in order you can use nextSpanTransition.

这里是带有SpannedString的示例,类似于问题中的示例. (A SpannableString的工作原理相同.)绿线表示跨度转换的位置.文本默认为黑色.

Here is an example with a SpannedString like the example in the question. (A SpannableString would work the same.) The green lines show where the span transitions are. The text is black by default.

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

The code finds the next span transition and then gets all the spans in the current range.

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

感谢

Thanks to this code for ideas.

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

Normally when looping through the spans you would choose a certain type of span. For example, if you wanted to remove all the foreground color spans, you could do the following:

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

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

请注意,这不适用于SpannedString,因为SpannedString中的跨度不可更改(请参见此答案).

Note that this wouldn't work with a SpannedString because the spans in a SpannedString are not mutable (see this answer).

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

If you wanted to get all the spans of any type you would set the type as Object.class.

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

如果要使用所有影响字符级别外观的跨度,则可以使用CharacterStyle.class.如果要在循环中将跨度进一步限制为属于MetricAffectingSpan的跨度,则可以这样做.

If you wanted all the spans that affect the appearance at the character level, you would use CharacterStyle.class. If within the loop you wanted to further limit the spans to those belonging to MetricAffectingSpan, you could do it like this.

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

这是跨度类型的一般分层细分.它可能不完整.阅读强大的概念Spans

Here is a general hierarchical breakdown of the span types. It may not be complete. Read Spans, a Powerful Concept for more information.

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

这篇关于如何在Android中的SpannedString或SpannableString中循环遍历的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆