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
这里写图片描述
这里写图片描述

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);

这里写图片描述

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();
    }

这里写图片描述

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);

这里写图片描述

 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);

这里写图片描述

8、RasterizerSpan 光栅效果
 SpannableStringBuilder builder = new SpannableStringBuilder("RasterizerSpan");
         RasterizerSpan rasterizerSpan = new RasterizerSpan(new Rasterizer());
         builder.setSpan(rasterizerSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

(没看出效果)
这里写图片描述

9、StrikethroughSpan 删除线
SpannableStringBuilder builder = new SpannableStringBuilder("StrikethroughSpan");
         StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
         builder.setSpan(strikethroughSpan, 5, 10, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

这里写图片描述

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);

这里写图片描述

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);

这里写图片描述

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);

这里写图片描述

 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);

这里写图片描述

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);

这里写图片描述

二、ParagraphStyle

这里写图片描述

影响段落层次的文本格式的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);

这里写图片描述

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);

这里写图片描述

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);

这里写图片描述

4、LeadingMarginSpan.Standard

文本段落的缩进样式

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

这里写图片描述

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);                

这里写图片描述

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);

这里写图片描述

7、TabStopSpan.Standard

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

三、UpdateAppearance

这里写图片描述

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

四、UpdateLayout

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

这里写图片描述

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值