TextView的内部链接与onClick事件冲突
在一个TextView内显示富态文本,例如指定文本的颜色、链接、大小等等
详见:TextView使用SpannableString设置复合文本
常用的如:Android使用TextView实现无下划线超链接
一般加入链接地址是直接Html.fromHTML(str)或者使用URLSpan,如下:
[java]view plaincopy
print?
String str ="浪人风子";
SpannableString spanText =newSpannableString(str +" ——CSDN");
spanText.setSpan(newURLSpan("http://blog.csdn.net/langrenfengzi"),0, str.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spanText);
textView.setMovementMethod(newLinkMovementMethod());
这样显示的应该是这样带有下划线:浪人风子——CSDN
对链接自动添加下划线及颜色略有不同。
继承URLSpan类,覆写updateDrawState方法:
[java]view plaincopy
print?
/**
*
* 没有下划线的URLSpan
*
*/
publicclassURLSpanWithoutUnderLineextendsURLSpan {
privateintcolor =0xff000000;
publicURLSpanWithoutUnderLine(String url,intcolor) {
super(url);
this.color = color;
}
publicURLSpanWithoutUnderLine(String url) {
super(url);
}
publicURLSpanWithoutUnderLine(Parcel src) {
super(src);
}
publicvoidsetColor(intcolor){
this.color= color;
}
@Override
publicvoidupdateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
//去掉下划线
ds.setColor(color);
//改成指定颜色
}
}
[java]view plaincopy
print?
String str ="浪人风子";
SpannableString spanText =newSpannableString(str +" ——CSDN");
spanText.setSpan(newURLSpanWithoutUnderLine("http://blog.csdn.net/langrenfengzi", Color.BLUE),0, str.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spanText);
textView.setMovementMethod(newLinkMovementMethod());
这样就实现了蓝色文字无下划线带链接的文字:浪人风子——CSDN
如果给TextView设置带点击事件OnClickListener,发现当点击链接的时候,点击事件也会被调用。
[java]view plaincopy
print?
textView.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
Log.d("test","onClick.");
}
});
我们想要实现的是当点击链接文字的时候只跳转链接不触发点击事件,当点击其他位置的时候只触发点击事件。
继承LinkMovementMethod类,重写onTouchEvent方法,使用一个flag标志何时点击了链接。
另外需要对TextView进行自定义控件,当flag标志的时候屏蔽点击事件。
[java]view plaincopy
print?
publicclassCommentTextViewextendsTextView {
publicbooleanlinkHit;
//内部链接是否被点击
publicCommentTextView(Context context) {
super(context);
}
publicCommentTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
publicCommentTextView(Context context, AttributeSet attrs,intdefStyle) {
super(context, attrs, defStyle);
}
@Override
publicbooleanperformClick() {
if(linkHit){
returntrue;
}
returnsuper.performClick();
}
@Override
publicbooleanonTouchEvent(MotionEvent event) {
linkHit =false;
returnsuper.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
【TextView的内部链接与onClick事件冲突】[java]view plaincopy
print?
publicclassCustomLinkMovementMethodextendsLinkMovementMethod {
staticCustomLinkMovementMethod sInstance;
@Override
publicbooleanonTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
intaction = event.getAction();
if(action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
intx = (int) event.getX();
inty = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
intline = layout.getLineForVertical(y);
intoff = 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);
}elseif(action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
if(widgetinstanceofCommentTextView){
((CommentTextView)widget).linkHit =true;
}
returntrue;
}else{
Selection.removeSelection(buffer);
super.onTouchEvent(widget, buffer, event);
returnfalse;
}
}
returnTouch.onTouchEvent(widget, buffer, event);
}
publicstaticCustomLinkMovementMethod getInstance() {
if(sInstance ==null){
sInstance =newCustomLinkMovementMethod();
}
returnsInstance;
}
}
CustomLinkMovementMethod的onTouchEvent基本拷贝LinkMovementMethod里对应方法的内容,需要修改的部分用为当有点击链接的时候设置flag变量linkHit.
另外切记,务必要重写静态方法getInstance(), 否则会调用父类的getInstance()实现,继而调用父类的onTouchEvent方法,实则没起作用。
在CommentTextView的onTouchEvent方法中的super.onTouchEvent(event)方法中会自动调用CustomLinkMovementMethod的onTouchEvent()方法,然后修改linkHit的值。
在performClick中判断,当linkHit为true的时候,直接返回true, 屏蔽调后续的onClickListener里的实现。
最终这样来调用:
[java]view plaincopy
print?
CommentTextView textView =newCommentTextView(this);
String str ="浪人风子";
SpannableString spanText =newSpannableString(str +" ——CSDN");
spanText.setSpan(newURLSpanWithoutUnderLine("http://blog.csdn.net/langrenfengzi", Color.BLUE),0, str.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spanText);
textView.setMovementMethod(CustomLinkMovementMethod.getInstance());
http://blog.csdn.net/langrenfengzi/article/details/39395567
推荐阅读
- 觉知的力量
- 投稿|一年卖82亿,新疆奶是怎么火的?
- python中删除文档的方法
- python中if-elif-else语句的使用注意
- python匿名函数的命名规则
- python函数定义的规则
- 投稿|从“梦核”进入“后室”,你的现实穿模了
- 2017-11-26
- app内中英文的转换
- 在S大的第47天(浑浑噩噩)