一、自定义圆角背景span

import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.text.style.ReplacementSpan;import android.view.View;public abstract class RoundedBackgroundSpan extends ReplacementSpan  {  private static int CORNER_RADIUS = 10;  private int backgroundColor = 0;  private int textColor = 0;  public RoundedBackgroundSpan(int backgroundColor, int textColor) {    this.backgroundColor = backgroundColor;    this.textColor = textColor;  }  @Override  public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {    return Math.round(paint.measureText(text, start, end));  }  @Override  public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,                   int bottom, Paint paint) {    RectF rectF = new RectF(x , top - 8, x + measureText(paint, text, start, end) - 10, y + 16);    paint.setColor(backgroundColor);    canvas.drawRoundRect(rectF, CORNER_RADIUS, CORNER_RADIUS, paint);    paint.setColor(textColor);    canvas.drawText(text, start, end, x, y, paint);  }  private float measureText(Paint paint, CharSequence text, int start, int end) {    return paint.measureText(text, start, end);  }  public abstract void onClick(View view);}

二、集成ClickableMovementMethod

import android.text.Layout;import android.text.Selection;import android.text.Spannable;import android.text.method.LinkMovementMethod;import android.text.style.ClickableSpan;import android.view.MotionEvent;import android.widget.TextView;public class ClickableMovementMethod extends LinkMovementMethod{  private static ClickableMovementMethod sInstance;  public static ClickableMovementMethod getInstance() {    if (sInstance == null) {      sInstance = new ClickableMovementMethod();    }    return sInstance;  }  @Override  public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {    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);      RoundedBackgroundSpan[] roundedBackgroundSpans = buffer.getSpans(off, off, RoundedBackgroundSpan.class);      if (roundedBackgroundSpans.length != 0) {        if (action == MotionEvent.ACTION_UP) {          roundedBackgroundSpans[0].onClick(widget);        } else if (action == MotionEvent.ACTION_DOWN) {          Selection.setSelection(buffer, buffer.getSpanStart(roundedBackgroundSpans[0]), buffer.getSpanEnd(roundedBackgroundSpans[0]));        }        return true;      } else {        Selection.removeSelection(buffer);      }    }    return false;  }}

三、将2者融合起来

import android.view.View;/** * Created by ningdai.cx on 15/11/26. */public class ClickableRoundedBackgroundSpan extends RoundedBackgroundSpan {  public ClickableRoundedBackgroundSpan(int backgroundColor, int textColor) {    super(backgroundColor, textColor);  }  @Override  public void onClick(View view) {  }}

四、具体使用场景

   TextView mTipContentTextView = (TextView) mActivity.findViewById(R.id.tip_content_text);   ...... // 设置MovementMethod;  mTipContentTextView.setMovementMethod(ClickableMovementMethod.getInstance()); // 新增SpannableString    SpannableString tagSpan = new SpannableString(tipContent);    int spanStartIndex;    int spanEndIndex;    int textColor = Color.parseColor("#666666");    int bgColor = Color.parseColor("#F5F5F5");    // 遍历需要变成圆角点击的tag列表    for (final String tag : tagArray) {      spanStartIndex = tipContent.indexOf(tag);      spanEndIndex = spanStartIndex + tag.length();      // 为SpannableString设置Span样式及点击事件      tagSpan.setSpan(new ClickableRoundedBackgroundSpan(bgColor, textColor) {                        @Override                        public void onClick(View view) {                          Toast.makeText(mActivity.getApplicationContext(), "U clicked " + tag,                                         Toast.LENGTH_SHORT).show();                          mTagClickListener.onTagClick(tag);                        }                      }, spanStartIndex, spanEndIndex,                      Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    }    mTipContentTextView.setText(tagSpan);    mTipContentTextView.setLineSpacing(0, 1.5f);

先把实现方案记录下来,具体原理可参见Android API 都讲的比较详细。

更多相关文章

  1. Android中带分割线的九宫格
  2. Android编程中的常见小问题ZZ
  3. Android系统自带样式Theme总结
  4. android 设置Button或者ImageButton的背景透明
  5. android 之 selector
  6. android——xml drawable实现背景样式
  7. android 设计比较美观的登录界面
  8. Android(安卓)Drawable系列(1):自定义背景以及注意事项
  9. 【Android开发基础】应用界面主题Theme使用方法

随机推荐

  1. Windows下Rk3288替换内核以及Launcher方
  2. Android动态换肤(一、应用内置多套皮肤)
  3. Android实用工具类-GrallyAndPhotoUtils
  4. Android异常捕获篇(下)---retrofit实现文件
  5. Android(安卓)Studio精彩案例(三)《模仿
  6. Android实用视图动画及工具系列之三:表情
  7. 摩托罗拉咬定Android不放松2011-01-17 14
  8. 轻听变色之谜-如何改变Android应用的主题
  9. 【设计模式与Android】迭代器模式——容
  10. Android(安卓)App驱动Arduino通过蓝牙控