zoukankan      html  css  js  c++  java
  • Android开发 SpannableString开发详解

    前言

      SpannableString,是google提供用来处理富文本的功能类.支持很多文本内容的效果变化.另外,它也是Android实现富文本编辑器的关键.

    关键API详解

         String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00"))
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    这是一个简单使用的demo,我们用这个demo来讲解一些关键点.

    这行代码的关键是setSpan(Object what, int start, int end, int flags)方法,这个方法在后面的文字处理将会一直使用到. setSpan有四个参数我们一个一个来讲解:

    第一个参数 Object what 这个参数主要是提供你需要改变字符串的效果实现类,后续会一一讲解并且给出效果图

    第二个参数 int start 这个参数是需要改变的字符串的起始位置

    第三个参数 int end 这个参数是需要改变的字符串的结束位置

    第四个参数 int flags 是一些字符串新增效果的影响范围,您可以参考这篇博客https://www.jianshu.com/p/1956e15c9a27这位大神讲解的十分详细了.本着就算是看懂了也要敲一敲代码记录的想法,下面也会说明一下常用的4种方法

    public static final int SPAN_INCLUSIVE_EXCLUSIVE = SPAN_MARK_MARK; 

    在前面/范围内增加字符,新增字符会跟随效果.

    在后面增加字符,新增字符不会跟随效果

    效果图:

     

    public static final int SPAN_INCLUSIVE_INCLUSIVE = SPAN_MARK_POINT;

    在前面/范围内/后面增加字符,新增字符会跟随效果.

    效果图:

    public static final int SPAN_EXCLUSIVE_EXCLUSIVE = SPAN_POINT_MARK;

    在范围内增加字符,新增字符会跟随效果.

    在前面/后面增加字符,新增字符不会跟随效果

    效果图:

    public static final int SPAN_EXCLUSIVE_INCLUSIVE = SPAN_POINT_POINT;

    在范围内/后面增加字符,新增字符会跟随效果.

    在前面增加字符,新增字符不会跟随效果.

    效果图:

    代码里还有一些其他的常量,但是测试后其他都是这四种基本里一样的效果.也实在是没看懂google的注释.....

    文字颜色

    以下代码将一段文字变成红色

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00"))
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);    

    ForegroundColorSpan 注意这个类是关键,他实现文字颜色改变.

    效果图:

    文字背景颜色

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new BackgroundColorSpan(Color.parseColor("#FFFF0C00"))
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    BackgroundColorSpan 注意这个类是关键,他实现文字背景颜色改变.

    效果图:

    字体

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new TypefaceSpan("sans-serif") //new TypefaceSpan(Typeface.SANS_SERIF) 或者使用这个方法
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图(系统自带的演示字体效果不明显):

    字体大小

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new AbsoluteSizeSpan(50)
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);    

    效果图:

    粗体

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new StyleSpan(Typeface.BOLD)
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    斜体

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new StyleSpan(Typeface.ITALIC)
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    粗体和斜体

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new StyleSpan(Typeface.BOLD_ITALIC)
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    另外还有一个Typeface.NORMAL  正常值就不演示了

    效果图:

    删除线

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new StrikethroughSpan()
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    下划线

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new UnderlineSpan()
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    上标

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new SuperscriptSpan()
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    下标

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new SubscriptSpan()
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    插入图片

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
            ImageSpan span = new ImageSpan(bitmap);
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(span
                    , 0
                    , 1
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    或者

            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher, null); //读取图片
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());//设置边界 图片显示范围
            ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);//ImageSpan.ALIGN_BASELINE 是对齐方式,这个是基线对齐
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(span
                    , 0
                    , 1
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    效果图:

    点击事件

            mTextView.setMovementMethod(LinkMovementMethod.getInstance());//这是关键,只有TextView添加这个后才能有点击事件
            mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改点击后的背景色
            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            ClickableSpan clickableSpan = new ClickableSpan() {
                @Override
                public void onClick(@NonNull View widget) {
                    Toast.makeText(MainActivity.this, "你点击了创业未半", Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void updateDrawState(@NonNull TextPaint ds) {
                    //改变选中文字的颜色或者样式,注意这里的TextPaint 其实是Paint,可以参考Paint的绘制添加其他效果.
                    ds.setColor(Color.RED);
    //                super.updateDrawState(ds);
                }
            };
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(clickableSpan
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    setMovementMethod是重中之重,只有设置了才能有 点击功能

    效果图:

    超链接

     电话

            mTextView.setMovementMethod(LinkMovementMethod.getInstance());//这是关键,只有TextView添加这个后才能有点击事件
            mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改点击后的背景色
            String content ="先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。";
            SpannableString spannableString = new SpannableString(content);
            spannableString.setSpan(new URLSpan("tel:10086")
                    , content.indexOf("创业")
                    , content.indexOf("而中")
                    , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            mTextView.setText(spannableString);

    注意!使用超链接,依然要设置setMovementMethod,另外URLSpan也是可以重写点击事件的.

     效果图:

     

    与使用Intent的超链接类似,也是支持几个通用的超链接,都需要你输入正确的前缀

    • mailto:123456@qq.com
    • http://www.baidu.com
    • sms:123456
    • mms:123456
    • geo: 38.899533,-77.036476

    其他Span

      上面的span只是一些常用的span演示,但是其实还有更多的span可以选择和使用,他们都在这个目录中.在这个目录下还有以下这些span.如果后续有时间我会一一实验使用这些span以判断他们的功能.

    放弃富文本效果,提取文本

    之前有端时间苦恼怎么提取不带富文本格式的文本,因为源代码的有很多方法并没有注释,所以蛋疼了很久..,后面突然发现,直接使用toString()方法就行

    spannableString.toString()

    END

  • 相关阅读:
    HDU2037
    python爬取邮箱
    HDU1058
    opengl 光照
    HDU1421
    <cocos2dx for window phone>一个简单的打地鼠游戏
    <cocos2dx for wp7>使用cocos2dx制作基于Tile地图的游戏:加入敌人和战斗(三)
    <WP7>(五)手把手教你写天气预报程序:ApplicationBar的使用和ListPicker的数据绑定
    <cocos2dx for wp7>在cocos2dx里面手势识别
    <cocos2dx for wp7>使用cocos2dx制作基于Tile地图的游戏:碰撞检测和收集物品(二)
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/11227711.html
Copyright © 2011-2022 走看看