- ClickableSpan要生效,需要给textview设置MovementMethod,否则点击是不生效的。在texview的setMovementMethod方法里面,会赋值给mMovement变量,在textview的ontouchevent方法里面有如下判断:
if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
if (mMovement != null) {
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
final boolean textIsSelectable = isTextSelectable();
//这里一般来说不会走,因为mAutoLinkMask 默认是0,一般也不会去设值
if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && textIsSelectable) {
ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),
getSelectionEnd(), ClickableSpan.class);
if (links.length > 0) {
links[0].onClick(this);
handled = true;
}
}
//、、、
}
如果没设置,不会回调mMovement.onTouchEvent方法,也不会调用里面ClickableSpan的onClick方法,代码如下:
@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);
ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
if (links.length != 0) {
if (action == MotionEvent.ACTION_UP) {
links[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(links[0]),
buffer.getSpanEnd(links[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
- ClickableSpan默认是有下划线的,而且点击后背景色不会变回来,要去掉下划线并实现点击后的背景恢复,需要重写ClickableSpan和LinkMovementMethod,实现如下:
去下划线:
public abstract class MyClickable extends ClickableSpan {
private int color;
private boolean underline = false;
public MyClickable(int color){
this.color = color;
}
public MyClickable(boolean underline, int color){
this.color = color;
this.underline = underline;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(color);//画笔颜色
ds.setUnderlineText(underline);//是否有下划线
}
}
背景恢复:
public class MyLInkMovementMethod extends LinkMovementMethod {
private static MyLInkMovementMethod instance;
public static MyLInkMovementMethod getInstance(){
if(instance==null){
instance = new MyLInkMovementMethod();
}
return instance;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
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 = buffer.getSpans(off, off, ClickableSpan.class);
if(link.length>0){
link[0].onClick(widget);
//在抬起的时候,重新设置span的背景色,这里也可以做其他操作,比如按下的颜色等等
buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT),
buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Selection.removeSelection(buffer);
return true;
}
}
return super.onTouchEvent(widget, buffer, event);
}
}
网友评论