【问题标题】:How to loop through the spans in a SpannedString or SpannableString in Android如何在 Android 中遍历 SpannedString 或 SpannableString 中的跨度
【发布时间】:2017-09-02 09:25:40
【问题描述】:

如果我有SpannedString(或SpannableStringlike this

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 的跨度?

【问题讨论】:

    标签: android loops spannablestring spanned


    【解决方案1】:

    按顺序遍历跨度

    您可以使用getSpans 获取SpannedSpannable String 中的跨度数组。但是,只需循环遍历getSpans 结果将not necessarily give them to you in order。要按顺序获取它们,您可以使用nextSpanTransition

    这是一个带有SpannedString 的示例,就像问题中的示例一样。 (SpannableString 的工作方式相同。)绿线显示跨度转换的位置。文字默认为黑色。

    代码找到下一个span过渡,然后获取当前范围内的所有span。

    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
    

    感谢this code 的想法。

    跨度类型

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

    // get spans
    ForegroundColorSpan[] spans = spannableString.getSpans(0, spannableString.length(), ForegroundColorSpan.class);
    
    // loop through spans
    for (ForegroundColorSpan span : spans) {
        spannableString.removeSpan(span);
    }
    

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

    如果您想获取任何类型的所有跨度,您可以将类型设置为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, a Powerful Concept了解更多信息。

    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
    

    【讨论】:

      猜你喜欢
      • 2013-07-06
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多