Spans

前言

基于Android API 23文档和源码。
SpannableStringBuilder
void setSpan (Object what, int start, int end, int flags)

函数意义:
给SpannableString或SpannableStringBuilder特定范围的字符串设定Span样式,可以设置多个(比如同时加上下划线和删除线等),Falg参数标识了当在所标记范围前和标记范围后紧贴着插入新字符时的动作,即是否对新插入的字符应用同样的样式。(这个后面会具体举例说明)

参数说明:
object what :对应的各种Span,后面会提到;
int start:开始应用指定Span的位置,索引从0开始
int end:结束应用指定Span的位置,特效并不包括这个位置。比如如果这里数为3(即第4个字符),第4个字符不会有任何特效。

int flags:取值有如下四个

Flag的作用是用来指定范围前后输入新的字符时,会不会应用效果的.
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
Spannable.SPAN_EXCLUSIVE_INCLUSIVE :前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
Spannable.SPAN_INCLUSIVE_EXCLUSIVE :前面包括,后面不包括。
Spannable.SPAN_INCLUSIVE_INCLUSIVE :前后都包括。

一、CharacterStyle

影响字符级的文本格式的Span
Spans_第1张图片
Spans_第2张图片

1、ForegroundColorSpan 文字字体的颜色

editText = (AppCompatEditText) findViewById(R.id.edit01);
        ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#ffee3d2b"));
        SpannableStringBuilder builder = new SpannableStringBuilder("ForegroundColorSpan");
        //前后都包括
        builder.setSpan(foregroundColorSpan, 1, 10, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        editText.setText(builder);

这里写图片描述

//前面包括,后面不包括
builder.setSpan(foregroundColorSpan, 1, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

//前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
builder.setSpan(foregroundColorSpan, 1, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE  );

这里写图片描述

//前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
builder.setSpan(foregroundColorSpan, 1, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE  );

这里写图片描述

2、BackgroundColorSpan 背景颜色

BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor("#ffee3d2b"));
        builder.setSpan(backgroundColorSpan, 1, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE  );

这里写图片描述

3、UnderlineSpan 下划线

UnderlineSpan underlineSpan = new UnderlineSpan();
builder.setSpan(underlineSpan, 1, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

4、SubscriptSpan 下标

SpannableStringBuilder builder = new SpannableStringBuilder("O2+C=CO2");
        SubscriptSpan subscriptSpan01  = new SubscriptSpan();
        builder.setSpan(subscriptSpan01, 1, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        SubscriptSpan subscriptSpan02  = new SubscriptSpan();
        builder.setSpan(subscriptSpan02, 7, builder.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第3张图片

5、SuperscriptSpan 上标

SpannableStringBuilder builder = new SpannableStringBuilder("22=4");
        SuperscriptSpan superscriptSpan = new SuperscriptSpan();
        builder.setSpan(superscriptSpan, 1, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

6、ClickableSpan 可点击的部分文字

        editText.setMovementMethod(LinkMovementMethod.getInstance());  
        SpannableStringBuilder builder = new SpannableStringBuilder("ClickableSpan");
        ClickableSpan clickableSpan = new ClickableSpan() {

    //该方法在系统开始绘制要设置样式的字符串之前调用,以便修改绘制文字的属性,例如,文字颜色、背景颜色等     
            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.RED);
                ds.setUnderlineText(false); 
            }
            @Override
            public void onClick(View widget) {
                translateY(msgView);
                textView.setText("ClickableSpan");
            }
        };
        // 设置点击后的颜色为透明
        // editText.setHighlightColor(Color.TRANSPARENT);
        builder.setSpan(clickableSpan, 5, builder.length(),
                Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
AnimatorSet animSet;
    private void translateY(View view){
        if(animSet!=null){
            animSet.removeAllListeners();
            animSet.cancel();
        }
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,-view.getHeight(),0);
        anim1.setDuration(500);
        anim1.setInterpolator(new AccelerateDecelerateInterpolator());
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, 0, -view.getHeight());
        anim2.setDuration(500);
        anim2.setStartDelay(3000);
        animSet = new AnimatorSet();        
        animSet.play(anim1).with(anim2);
        animSet.start();
    }

Spans_第4张图片

7、MaskFilterSpan 修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)

 SpannableStringBuilder builder = new
         SpannableStringBuilder("MaskFilterSpan");
         MaskFilterSpan maskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(4, BlurMaskFilter.Blur.NORMAL));
         builder.setSpan(maskFilterSpan, 1, builder.length(),
         Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第5张图片

 editText.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         SpannableStringBuilder builder = new SpannableStringBuilder("EmbossMaskFilter");
         EmbossMaskFilter embossMaskFilter = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
         MaskFilterSpan maskFilterSpan = new MaskFilterSpan(embossMaskFilter){
             @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.RED);
            }
         };
         builder.setSpan(maskFilterSpan, 1, builder.length(),
         Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第6张图片

8、RasterizerSpan 光栅效果

 SpannableStringBuilder builder = new SpannableStringBuilder("RasterizerSpan");
         RasterizerSpan rasterizerSpan = new RasterizerSpan(new Rasterizer());
         builder.setSpan(rasterizerSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

(没看出效果)
Spans_第7张图片

9、StrikethroughSpan 删除线

SpannableStringBuilder builder = new SpannableStringBuilder("StrikethroughSpan");
         StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
         builder.setSpan(strikethroughSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第8张图片

10、SuggestionSpan 占位符 (API 14)

 SpannableStringBuilder builder = new SpannableStringBuilder("SuggestionSpan");
         SuggestionSpan suggestionSpan  = new SuggestionSpan(
                 this, 
                 new String[]{"SuggestionSpan1","SuggestionSpan2","SuggestionSpan3"}, 
                 SuggestionSpan.FLAG_EASY_CORRECT);
         builder.setSpan(suggestionSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第9张图片

11、AbsoluteSizeSpan 字体的绝对大小

 SpannableStringBuilder builder = new SpannableStringBuilder("SuggestionSpan");
         AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 30, getResources().getDisplayMetrics()));
         builder.setSpan(absoluteSizeSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

12、RelativeSizeSpan 字体的相对大小

SpannableStringBuilder builder = new SpannableStringBuilder("SuggestionSpan");
         RelativeSizeSpan  absoluteSizeSpan = new RelativeSizeSpan(1.5f);
         builder.setSpan(absoluteSizeSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第10张图片

13、LocaleSpan (API 17 Android 4.2 Jelly Bean)

14、ScaleXSpan 基于x轴的缩放

 SpannableStringBuilder builder = new SpannableStringBuilder("ScaleXSpan");
         ScaleXSpan scaleXSpan = new ScaleXSpan(2.5f);
         builder.setSpan(scaleXSpan, 5, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

15、StyleSpan 字体样式:粗体、斜体等

SpannableStringBuilder builder = new SpannableStringBuilder("StyleSpan ");
         //常用的字体类型名称还有:
         //Typeface.DEFAULT //常规字体类型
         //Typeface.DEFAULT_BOLD //黑体字体类型
         //Typeface.MONOSPACE //等宽字体类型
         //Typeface.SANS_SERIF //sans serif字体类型
         //常用的字体风格名称还有:
         //Typeface.BOLD //粗体
         //Typeface.BOLD_ITALIC //粗斜体
         //Typeface.ITALIC //斜体
         //Typeface.NORMAL //常规
         StyleSpan  styleSpan = new StyleSpan(Typeface.ITALIC);
         builder.setSpan(styleSpan, 5, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

16、TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)

 SpannableStringBuilder builder = new SpannableStringBuilder("TextAppearanceSpan");
         TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(this, android.R.style.TextAppearance_DeviceDefault_Small); 
         builder.setSpan(textAppearanceSpan, 5, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

17、TypefaceSpan 文本字体

SpannableStringBuilder builder = new SpannableStringBuilder("TypefaceSpan");
         TypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif");
         builder.setSpan(typefaceSpan, 5, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

18、URLSpan 文本超链接

 editText.setMovementMethod(LinkMovementMethod.getInstance());
         SpannableStringBuilder builder = new SpannableStringBuilder("URLSpan");
         URLSpan urlSpan = new URLSpan("https://www.baidu.com");
         builder.setSpan(urlSpan, 1, 5, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第11张图片

 editText.setMovementMethod(LinkMovementMethod.getInstance());
         SpannableStringBuilder builder = new SpannableStringBuilder("URLSpan1701111111");
         URLSpan urlSpan = new URLSpan("tel:1701111111");
         builder.setSpan(urlSpan, 7, builder.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Spans_第12张图片

19、DynamicDrawableSpan


SpannableStringBuilder builder = new SpannableStringBuilder("DynamicDrawableSpan");
        //基于文本基线或底部对齐
        DynamicDrawableSpan drawableSpan =
                 new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) {
                    @Override
                    public Drawable getDrawable() {
                        Drawable d = getResources().getDrawable(R.drawable.phone_image05);
                        d.setBounds(0, 0, 100, 100);
                        return d;
                    }
                };
                DynamicDrawableSpan drawableSpan2 = new DynamicDrawableSpan(
                DynamicDrawableSpan.ALIGN_BOTTOM) {
                    @Override
                    public Drawable getDrawable() {
                          Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
                          d.setBounds(0, 0, 100, 100);
                                return d;
                            }
                        };
         builder.setSpan(drawableSpan, 3, 4, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
         builder.setSpan(drawableSpan2, 7, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

20、ImageSpan

SpannableStringBuilder builder = new SpannableStringBuilder("ImageSpan");
        Drawable d = getResources().getDrawable(R.drawable.phone_image05);
        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
        builder.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Spans_第13张图片

二、ParagraphStyle

Spans_第14张图片

影响段落层次的文本格式的Span

1、BulletSpan

BulletSpan影响段落层次的文本格式。它可以给段落的开始处加上项目符号。

 SpannableStringBuilder builder = new SpannableStringBuilder("BU\n");
          //gapWidth:项目符号和文本之间的间隙
          //color: 项目符号的颜色,默认为透明
          builder.setSpan(new BulletSpan(30,Color.RED), 0, 1,  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          builder.append("ll\n");
          builder.setSpan(new BulletSpan(30,Color.BLACK), 3,4,  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          builder.append("ETSPAN\nM");
          builder.setSpan(new BulletSpan(30,Color.GREEN), 6,7,  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          builder.setSpan(new BulletSpan(30,Color.BLUE), builder.length()-1,builder.length(),  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Spans_第15张图片

2、QuoteSpan

QuoteSpan影响段落层次的文本格式。它可以给一个段落加上垂直的引用线。

 SpannableStringBuilder builder = new SpannableStringBuilder("BU\n");
          builder.setSpan(new QuoteSpan(Color.RED), 0, 1,  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          builder.append("ll\n");
          builder.setSpan(new QuoteSpan(Color.BLACK), 3,4,  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          builder.append("ETSPAN\nM");
          builder.setSpan(new QuoteSpan(Color.GREEN), 6,7,  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          builder.setSpan(new QuoteSpan(Color.BLUE), builder.length()-1,builder.length(),  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Spans_第16张图片

3、AlignmentSpan.Standard

AlignmentSpan.Standard影响段落层次的文本格式。它可以把段落的每一行文本按正常、居中、相反的方式对齐。

 SpannableStringBuilder builder = new SpannableStringBuilder("Unless required by applicable law or agreed to in writing, software"+
                 "distributed under the License is distributed on an \"AS IS\" BASIS,"+
                 " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."+
                 " See the License for the specific language governing permissions and"+
                 " limitations under the License.");
          builder.setSpan(new AlignmentSpan.Standard(Alignment.ALIGN_CENTER), 0,builder.length(),  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Spans_第17张图片

4、LeadingMarginSpan.Standard

文本段落的缩进样式

 //first  首行缩进的像素
 //rest   剩余行缩进的像素
builder.setSpan( new LeadingMarginSpan.Standard(50,100), 0,builder.length(),  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Spans_第18张图片

5、DrawableMarginSpan

图片+Margin样式


 SpannableStringBuilder builder = new SpannableStringBuilder("Unless required by applicable law or a\ngreed to in writing, software"+
                     "distributed under the License is distributed on an \"AS IS\" BASIS,"+
                     " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."+
                     " See the License for the specific language governing permissions and"+
                     " limitations under the License.");
     Drawable drawable = getResources().getDrawable(R.drawable.phone_image05);
          //Drawable 用于显示的图片
          //pad 图片和文字的距
          builder.setSpan(new DrawableMarginSpan(drawable, 10), 38,builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);                

Spans_第19张图片

6、IconMarginSpan

图标+Margin样式,该类与DrawableMarginSpan使用上很相似

  SpannableStringBuilder builder = new SpannableStringBuilder("Unless required by applicable law or a\ngreed to in writing, software"+
                     "distributed under the License is distributed on an \"AS IS\" BASIS,"+
                     " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."+
                     " See the License for the specific language governing permissions and"+
                     " limitations under the License.");
  BitmapFactory.Options options = new Options();
          options.inSampleSize=2;
          Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.phone_image05, options);
          builder.setSpan(new IconMarginSpan(bitmap, 50), 38,builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Spans_第20张图片

7、TabStopSpan.Standard

制表位偏移样式,距离每行的leading margin的偏移量,据测试在首行加入制表符时才产生效果

三、UpdateAppearance

Spans_第21张图片

修改字符级别的文本外观的Span

四、UpdateLayout

修改字符级文本度量|大小的Span

Spans_第22张图片

参考:http://blog.csdn.net/harvic880925/article/details/38984705
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0305/2535.html

你可能感兴趣的:(android,android)