利用Span实现TextView/EditText的灵活表现--改变字体外观,添加点击,超链接

1 TextView和EditText灵活设置文字格式

TextView和EditText都可以设置纯文本的字符串,但是当一个字符串中需要设置不同的文字格式或者插入图片时,我们不可能去设置多个TextView+ImageView来实现,那样要累死了。(话说,刚开始我就是动态添加四个TextView来实现一个效果,好囧)。我们知道,方法setText(CharSequence text)中接收的是CharSequence。而SpannableString和SpannableStringBuilder是其实现类,是可以直接赋值的,并且,两者的setSpan()方法可以设置一些格式对象(例如字体大小,下划线,替换为图片,等),这就可以实现富文本了。

接口 Spannable--->Spanned--->CharSequence

实现子类:

|--Editable

|--SpannableString 

|--SpannableStringBuilder(-->Editale)

Spannable中定义了抽象方法:setSpan(Object what, int start, int end, int flags)和removeSpan(Object what)。这两个方法实现了对字符串的灵活编辑。


实现效果如下:

利用Span实现TextView/EditText的灵活表现--改变字体外观,添加点击,超链接_第1张图片

2 各Span的简单应用

以下是一些常用到的一些Span

    |-- ForegroundColorSpan

    |-- BackgroundColorSpan

    |-- StyleSpan

    |-- TypefaceSpan

    |-- ImageSpan

    |-- URLSpan

    |-- UnderlineSpan

    |-- StrikethroughSpan(删除线)

具体没啥说的,直接看代码

 
   
  1. private void setSpan() {
  2.        SpannableString spannableString = new SpannableString("君不见黄河之水天上来,");
  3.        SpannableString spannableString2 = new SpannableString("奔流到海不复回。");
  4.        SpannableString spannableString3 = new SpannableString("君不见高堂明镜悲白发,");
  5.        SpannableString spannableString4 = new SpannableString("朝如青丝暮成雪。");
  6.        SpannableString spannableString5 = new SpannableString("人生得意须尽欢。");
  7.        SpannableString spannableString6 = new SpannableString("莫使金樽空对月。");
  8.        ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.GREEN);
  9.        BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.CYAN);// 同ForegroundColorSpan应用一样
  10.        AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(32,true);// 32dp
  11.        UnderlineSpan underlineSpan = new UnderlineSpan();
  12.        // 文本字体格式,加粗,倾斜
  13.        StyleSpan styleSpan = new StyleSpan(Typeface.BOLD_ITALIC);
  14.        // 这四种flags的显示效果是一样的,包前不包后
  15.        spannableString.setSpan(foregroundColorSpan,1,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  16.        spannableString.setSpan(styleSpan, 1, 5, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
  17.        spannableString2.setSpan(underlineSpan, 1, 5, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
  18.        spannableString3.setSpan(absoluteSizeSpan, 1, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
  19.        spannableString4.setSpan(backgroundColorSpan, 1, 5, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
  20.        ImageSpan imageSpan = new ImageSpan(this,R.mipmap.iv_lyf);
  21.        spannableString5.setSpan(imageSpan, 1, 4, Spanned.SPAN_COMPOSING);
  22.        Drawable drawable = getResources().getDrawable(R.mipmap.iv_lyf);
  23.        drawable.setBounds(0, 0, drawable.getIntrinsicWidth()/3, drawable.getIntrinsicHeight()/3);//缩小为1/3
  24.        ImageSpan imageSpan1 = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
  25.        spannableString6.setSpan(imageSpan1,1,5,Spanned.SPAN_COMPOSING);
  26.        textView.setText(spannableString);
  27.        textView2.setText(spannableString2);
  28.        textView3.setText(spannableString3);
  29.        textView4.setText(spannableString4);
  30.        textView5.setText(spannableString5);
  31.        textView6.setText(spannableString6);
  32.        // 以上四种span对于新增加的文字有效果
  33. //        editText.setText(spannableString);// Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 在span的文字前后新加文字都不会有span设置的效果
  34. //        editText.setText(spannableString2);// Spanned.SPAN_EXCLUSIVE_INCLUSIVE 在span的文字前后新加文字,前边无效果,后边会复用效果
  35. //        editText.setText(spannableString3);// Spanned.SPAN_INCLUSIVE_EXCLUSIVE 在span的文字前后新加文字,前边会复用效果,后边无效果
  36.        editText.setText(spannableString4);// Spanned.SPAN_INCLUSIVE_INCLUSIVE 在span的文字前后新加文字,前边和后边都会复用效果
  37.    }

以上是SpannableString的应用,还用一个SpannableStringBuilder,他们两个区别就是,后者可以通过append()方法动态添加文本。其他用法相同。如下:

 
   
  1.  private void setSpan2() {
  2.        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("天生我材必有用,");
  3.        ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);
  4.        StrikethroughSpan strikethroughSpan =new StrikethroughSpan();
  5.        spannableStringBuilder.setSpan(foregroundColorSpan,0,3,Spanned.SPAN_COMPOSING);
  6.        spannableStringBuilder.append("千金散尽还复来。");
  7.        spannableStringBuilder.setSpan(strikethroughSpan,3,12,Spanned.SPAN_COMPOSING);
  8.        textView7.setText(spannableStringBuilder);
  9.    }

3 利用ClickableSpan实现可点击文本

模拟点赞人的联系显示,且可点击。

 
   
  1.  private void setMoreLikers(){
  2.        // 构造多个超链接的html, 通过选中的位置来获取用户名
  3.        StringBuilder sbBuilder = new StringBuilder();
  4.        for (int i = 0; i < 15; i++) {
  5.            sbBuilder.append("liker" + i + "、");
  6.        }
  7.        String likers = sbBuilder.substring(0, sbBuilder.lastIndexOf("、")).toString();
  8.        textView8.setMovementMethod(LinkMovementMethod.getInstance());//
  9.        textView8.setText(addClickablePart(likers), TextView.BufferType.SPANNABLE);
  10.    }
  11.    /**
  12.     * ClickableSpan 可点击的文本
  13.     * @param str
  14.     * @return
  15.     */
  16.    private SpannableStringBuilder addClickablePart(String str) {
  17.        Drawable drawable = getResources().getDrawable(R.mipmap.ic_like);
  18.        drawable.setBounds(0,0,30,30);// 设置大小
  19.        // 赞的图标
  20.        ImageSpan span = new ImageSpan(drawable, DynamicDrawableSpan.ALIGN_BASELINE);
  21.        SpannableString spanStr = new SpannableString("l");// 被替换的
  22.        spanStr.setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
  23.        // 将赞的图标和赞的人名拼接
  24.        SpannableStringBuilder ssb = new SpannableStringBuilder(spanStr);
  25.        ssb.append(str) ;
  26.        String[] likers = str.split("、");
  27.        if (likers.length > 0) {
  28.            for (int i = 0; i < likers.length; i++) {
  29.                final String name = likers[i];
  30.                final int start = str.indexOf(name) + spanStr.length();
  31.                ssb.setSpan(new ClickableSpan() {
  32.                    @Override
  33.                    public void onClick(View widget) {
  34.                        Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show();
  35.                    }
  36.                    @Override
  37.                    public void updateDrawState(TextPaint ds) {
  38.                        super.updateDrawState(ds);
  39.                        // 设置文本颜色
  40.                        ds.setColor(Color.RED);
  41.                        // 去掉下划线
  42.                        ds.setUnderlineText(false);
  43.                        ds.setTextSize(30.0f);
  44.                    }
  45.                }, start, start + name.length(), Spanned.SPAN_COMPOSING);
  46.            }
  47.        }
  48.        return ssb.append("赞了您.");
  49.    }


4 URLSpan用法

URLSpan urlSpan = new URLSpan("tel:10086");

URLSpan默认都设置了ClickableSpan,都是可点击的。

"tel:":电话

"mailto:":邮件

"http:":网址

"sms:":短信

"geo:":地图(需要fq)

 
   
  1. /**
  2. * 点击电话超链接,拨打电话
  3. *
  4. */
  5. private void setUrlSpan(){
  6. SpannableString spannableString = new SpannableString("电话");
  7. final URLSpan urlSpan = new URLSpan("tel:10086");
  8. spannableString.setSpan(urlSpan, 0, 2, Spanned.SPAN_COMPOSING);
  9. textView9.setMovementMethod(LinkMovementMethod.getInstance());
  10. textView9.setText(spannableString);
  11. }
  12. /**
  13. * 网址超链接 默认是可点击跳转的
  14. */
  15. private void setUrlSpan2(){
  16. SpannableString spannableString = new SpannableString("网址");
  17. final URLSpan urlSpan2 = new URLSpan("http://www.csdn.net");
  18. spannableString.setSpan(urlSpan2, 0, 2, Spanned.SPAN_COMPOSING);
  19. textView10.setMovementMethod(LinkMovementMethod.getInstance());
  20. textView10.setText(spannableString);
  21. }

你可能感兴趣的:(利用Span实现TextView/EditText的灵活表现--改变字体外观,添加点击,超链接)