在一个TextView内显示富态文本,例如指定文本的颜色、链接、大小等等
详见: TextView使用SpannableString设置复合文本
常用的如: Android使用TextView实现无下划线超链接
一般加入链接地址是直接Html.fromHTML(str)或者使用URLSpan,如下:
String str = "浪人风子";
SpannableString spanText = new SpannableString(str + " ——CSDN");
spanText.setSpan(new URLSpan("http://blog.csdn.net/langrenfengzi"), 0, str.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spanText);
textView.setMovementMethod(new LinkMovementMethod());
这样显示的应该是这样带有下划线:
浪人风子 ——CSDN
对链接自动添加下划线及颜色略有不同。
继承URLSpan类,覆写updateDrawState方法:
/**
*
* 没有下划线的URLSpan
*
*/
public class URLSpanWithoutUnderLine extends URLSpan {
private int color = 0xff000000;
public URLSpanWithoutUnderLine(String url, int color) {
super(url);
this.color = color;
}
public URLSpanWithoutUnderLine(String url) {
super(url);
}
public URLSpanWithoutUnderLine(Parcel src) {
super(src);
}
public void setColor(int color){
this.color = color;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);//去掉下划线
ds.setColor(color);//改成指定颜色
}
}
String str = "浪人风子";
SpannableString spanText = new SpannableString(str + " ——CSDN");
spanText.setSpan(new URLSpanWithoutUnderLine("http://blog.csdn.net/langrenfengzi", Color.BLUE), 0, str.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spanText);
textView.setMovementMethod(new LinkMovementMethod());
这样就实现了蓝色文字无下划线带链接的文字:
浪人风子 ——CSDN
如果给TextView设置带点击事件OnClickListener,发现当点击链接的时候,点击事件也会被调用。
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("test", "onClick.");
}
});
继承LinkMovementMethod类,重写onTouchEvent方法,使用一个flag标志何时点击了链接。
另外需要对TextView进行自定义控件,当flag标志的时候屏蔽点击事件。
public class CommentTextView extends TextView {
public boolean linkHit;//内部链接是否被点击
public CommentTextView(Context context) {
super(context);
}
public CommentTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CommentTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean performClick() {
if(linkHit){
return true;
}
return super.performClick();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
linkHit = false;
return super.onTouchEvent(event);
}
}
参考:http://www.cnblogs.com/TerryBlog/archive/2013/04/02/2994815.html
http://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable
public class CustomLinkMovementMethod extends LinkMovementMethod {
static CustomLinkMovementMethod 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);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
if(widget instanceof CommentTextView){
((CommentTextView)widget).linkHit = true;
}
return true;
} else {
Selection.removeSelection(buffer);
super.onTouchEvent(widget, buffer, event);
return false;
}
}
return Touch.onTouchEvent(widget, buffer, event);
}
public static CustomLinkMovementMethod getInstance() {
if(sInstance == null){
sInstance = new CustomLinkMovementMethod();
}
return sInstance;
}
}
CustomLinkMovementMethod的onTouchEvent基本拷贝LinkMovementMethod里对应方法的内容,需要修改的部分用为当有点击链接的时候设置flag变量linkHit.
另外切记,务必要重写静态方法getInstance(), 否则会调用父类的getInstance()实现,继而调用父类的onTouchEvent方法,实则没起作用。
在CommentTextView的onTouchEvent方法中的super.onTouchEvent(event)方法中会自动调用CustomLinkMovementMethod的onTouchEvent()方法,然后修改linkHit的值。
在performClick中判断,当linkHit为true的时候,直接返回true, 屏蔽调后续的onClickListener里的实现。
最终这样来调用:
CommentTextView textView = new CommentTextView(this);
String str = "浪人风子";
SpannableString spanText = new SpannableString(str + " ——CSDN");
spanText.setSpan(new URLSpanWithoutUnderLine("http://blog.csdn.net/langrenfengzi", Color.BLUE), 0, str.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spanText);
textView.setMovementMethod(CustomLinkMovementMethod.getInstance());