Android成长之旅思科DevNet

Android实现微博复文本效果SpannableString

2016-12-02  本文已影响111人  风的背影6885

Github SpannableStringDemo 地址
Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能:
1、BackgroundColorSpan 背景色
2、ClickableSpan 文本可点击,有点击事件
3、ForegroundColorSpan 文本颜色(前景色)
4、MaskFilterSpan 修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)
5、MetricAffectingSpan 父类,一般不用
6、RasterizerSpan 光栅效果
7、StrikethroughSpan 删除线(中划线)
8、SuggestionSpan 相当于占位符
9、UnderlineSpan 下划线
10、AbsoluteSizeSpan 绝对大小(文本字体)
11、DynamicDrawableSpan 设置图片,基于文本基线或底部对齐。
12、ImageSpan 图片
13、RelativeSizeSpan 相对大小(文本字体)
14、ReplacementSpan 父类,一般不用
15、ScaleXSpan 基于x轴缩放
16、StyleSpan 字体样式:粗体、斜体等
17、SubscriptSpan 下标(数学公式会用到)
18、SuperscriptSpan 上标(数学公式会用到)
19、TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)
20、TypefaceSpan 文本字体
21、URLSpan 文本超链接

flags 常用的几种属性:

Spanned.SPAN_INCLUSIVE_EXCLUSIVE
从起始下标到结束下标,包括起始下标不包含结束坐标Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
从起始下标到结束下标,但都不包括起始下标和结束下标Spanned.SPAN_INCLUSIVE_INCLUSIVE
从起始下标到终了下标,同时包括起始下标和结束下标Spanned.SPAN_EXCLUSIVE_INCLUSIVE
从起始下标到终了下标,包括结束下标不包含起始坐标

Paste_Image.png

各种情况设置

1、BackgroundColorSpan 背景色

/**
    * 设置背景色
    * @param str
    * @param color
    * @param start
    * @param end
    */
   private void setBackground(String str, int color,int start,int end){
       SpannableString spannableString = new SpannableString(str);
       BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(color);
       spannableString.setSpan(backgroundColorSpan,start, end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
   }

2、ClickableSpan 文本可点击,有点击事件

/**
    *设置文本可点击,有点击事件
    * @param str
    * @param start
    * @param end
    */
   private void setClickable(String str,int start ,int end){
       SpannableString spannableString  = new SpannableString(str);
       String sub = str.substring(start,end);
       spannableString.setSpan(new MyClickableSpan(sub),start,end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv2.setText(spannableString);
   }

   class  MyClickableSpan extends ClickableSpan{
       String str = null;

       public MyClickableSpan(String str) {
           this.str = str;
       }

       @Override
       public void updateDrawState(TextPaint ds) {
           super.updateDrawState(ds);
           ds.setUnderlineText(false);
       }
       @Override
       public void onClick(View view) {
           //TODO 自定义点击事件
           Toast.makeText(OtherActivity.this, str, Toast.LENGTH_SHORT).show();
       }
   }

文字设置点击事件

//设置使自定义的点击事件生效
tvText.setMovementMethod(LinkMovementMethod.getInstance());

解决文字可点击ListView和RecycleView的Item点击失效

1.重写一个触摸事件

/**
* @author WJ
* @项目名称: SpannableStringDemo
* @创建时间: 2016年12月02日
* @描述:  解决复文本点击事件抢占ListView和RecycleView的Item点击事件
*/

public class MyLinkMovementMethod  implements View.OnTouchListener{
   public static MyLinkMovementMethod getInstance() {
       if (sInstance == null)
           sInstance = new MyLinkMovementMethod();

       return sInstance;
   }

   private static MyLinkMovementMethod sInstance;

   @Override
   public boolean onTouch(View v, MotionEvent event) {
       boolean ret = false;
       CharSequence text = ((TextView) v).getText();
       Spannable stext = Spannable.Factory.getInstance().newSpannable(text);
       TextView widget = (TextView) v;
       int action = event.getAction();

       if (action == MotionEvent.ACTION_UP ||
               action == MotionEvent.ACTION_DOWN) {
           int x = (int) event.getX();
           int y = (int) event.getY();

           x -= widget.getTotalPaddingLeft();
           y -= widget.getTotalPaddingTop();

           x += widget.getScrollX();
           y += widget.getScrollY();

           Layout layout = widget.getLayout();
           int line = layout.getLineForVertical(y);
           int off = layout.getOffsetForHorizontal(line, x);

           ClickableSpan[] link = stext.getSpans(off, off, ClickableSpan.class);

           if (link.length != 0) {
               if (action == MotionEvent.ACTION_UP) {
                   link[0].onClick(widget);
               }
               ret = true;
           }
       }
       return ret;
   }
}

2.给textView设置触摸事件

tvText.setOnTouchListener(MyLinkMovementMethod.getInstance());

3、ForegroundColorSpan 文本颜色(前景色)

/**
    * 设置前景色
    * @param str
    * @param color
    */
   private void setForeground(String str, int color,int start,int end){
       SpannableString spannableString = new SpannableString(str);
       ForegroundColorSpan colorSpan = new ForegroundColorSpan(color);
       spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

   }

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


   /**
    * 设置模糊与浮雕
    * @param str
    */
   private void setMaskFilterSpan(String str) {
       SpannableString spannableString = new SpannableString(str);
       int length = spannableString.length();
       //模糊(BlurMaskFilter)
       MaskFilterSpan maskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(3, BlurMaskFilter.Blur.OUTER));
       spannableString.setSpan(maskFilterSpan, 0, length - 14, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

       //浮雕(EmbossMaskFilter)
       //direction 是float数组,定义长度为3的数组标量[x,y,z],来指定光源的方向

       //ambient 取值在0到1之间,定义背景光 或者说是周围光

      // specular 定义镜面反射系数。

      // blurRadius 模糊半径。
       maskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{1, 1, 3}, 1.5f, 8, 3));

       spannableString.setSpan(maskFilterSpan, length - 16, length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

       tv5.setText(spannableString);

   }

5、RelativeSizeSpan 相对大小(文本字体)

/**
    * 设置文字相对大小
    * @param str
    */
   private void setRelativeSizeSpan(String str){
       SpannableString spannableString = new SpannableString(str);

       RelativeSizeSpan sizeSpan01 = new RelativeSizeSpan(1.2f);
       RelativeSizeSpan sizeSpan02 = new RelativeSizeSpan(1.4f);
       RelativeSizeSpan sizeSpan03 = new RelativeSizeSpan(1.6f);
       RelativeSizeSpan sizeSpan04 = new RelativeSizeSpan(1.8f);
       RelativeSizeSpan sizeSpan05 = new RelativeSizeSpan(1.6f);
       RelativeSizeSpan sizeSpan06 = new RelativeSizeSpan(1.4f);
       RelativeSizeSpan sizeSpan07 = new RelativeSizeSpan(1.2f);

       spannableString.setSpan(sizeSpan01, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       spannableString.setSpan(sizeSpan02, 1, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       spannableString.setSpan(sizeSpan03, 2, 3, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       spannableString.setSpan(sizeSpan04, 3, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       spannableString.setSpan(sizeSpan05, 4, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       spannableString.setSpan(sizeSpan06, 5, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       spannableString.setSpan(sizeSpan07, 6, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv6.setText(spannableString);
   }

6、StrikethroughSpan 删除线(中划线)

/**
    * 为文字设置删除线
    * @param str
    * @param start
    * @param end
    */
   private void setDeleteLine(String str,int start,int end){
       SpannableString spannableString = new SpannableString(str);
       StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
       spannableString.setSpan(strikethroughSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv4.setText(spannableString);
   }

7、SuggestionSpan 相当于占位符

相当于占位符,一般用在EditText输入框中。当双击此文本时,会弹出提示框选择一些建议(推荐的)文字,选中的文本将替换此占位符。在输入法上用的较多。

8、UnderlineSpan 下划线

/**
    * 设置下划线
    *
    * @param str
    * @param start
    * @param end
    */
   private void setUnderLineSpan(String str, int start, int end) {
       SpannableString spannableString = new SpannableString(str);
       spannableString.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv7.setText(spannableString);
   }

9、DynamicDrawableSpan 设置图片,基于文本基线或底部对齐。

/**
    * 设置图片,基于文本基线或底部对齐
    * @param start
    * @param end
    */
   private void setDynamicDrawableSpan(int start, int end) {
       SpannableString spannableString = new SpannableString("这是测试字符串,这是测试字符串");
//        DynamicDrawableSpan.ALIGN_BOTTOM和DynamicDrawableSpan.ALIGN_BASELINE
       DynamicDrawableSpan drawableSpan = new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) {
                   @Override
                   public Drawable getDrawable() {
                       Drawable d = getResources().getDrawable(R.mipmap.ic_launcher);
                       d.setBounds(0, 0, 50, 50);
                       return d;
                   }
               };
       spannableString.setSpan(drawableSpan, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
       tv8.setText(spannableString);
   }

10、ImageSpan 图片

/**
    * 图片
    * @param start
    * @param end
    */
   private void setImageSpan(int start, int end){
       SpannableString spannableString = new SpannableString("这是图片哦");
       Drawable drawable = getResources().getDrawable(R.mipmap.smail);
       drawable.setBounds(0, 0, 42, 42);
       ImageSpan imageSpan = new ImageSpan(drawable);
       spannableString.setSpan(imageSpan, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv9.setText(spannableString);
   }

11、URLSpan 文本超链接

   /**
    * 设置超链接
    * @param start
    * @param end
    */
   private void setUrlSpan(int start, int end){
       SpannableString spannableString = new SpannableString("这是超链接哦");
       spannableString.setSpan(new MyUrlSpan("http://www.baidu.com"),start,end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv10.setMovementMethod(LinkMovementMethod.getInstance());
       tv10.setText(spannableString);
   }

   class  MyUrlSpan extends URLSpan{

       public MyUrlSpan(String url) {
           super(url);
       }

       @Override
       public void onClick(View widget) {
           super.onClick(widget);
           // TODO 可自定义点击事件
       }
   }

12、SubscriptSpan 下标(数学公式会用到)

/**
    *设置下标
    * @param start
    * @param end
    */
   private void setSubscriptSpan(int start, int end){
       SpannableString spannableString = new SpannableString("这是我的下标");
       SubscriptSpan subscriptSpan = new SubscriptSpan();
       spannableString.setSpan(subscriptSpan,start,end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv11.setText(spannableString);
   }

13、SuperscriptSpan 上标(数学公式会用到)

/**
    * 设置上标
    *
    * @param start
    * @param end
    */
   private void setSuperscriptSpan(int start, int end) {
       SpannableString spannableString = new SpannableString("这是我的上标");
       SuperscriptSpan superscriptSpan = new SuperscriptSpan();
       spannableString.setSpan(superscriptSpan, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
       tv12.setText(spannableString);
   }

另外SpannableStringBuilder与StringBuilder的用法类似,可添加多个不同类型的字符进行拼接,使用append();方法进行多类型SpannableString字符的拼接。

上一篇下一篇

猜你喜欢

热点阅读