前言

我们在给TextView设置超链接的时候,可能最简单的,Android已经给出了一个非常的简单的做法就是:
在xml中设置:

android:autoLink="web"  

或者

//sp为SpannableStringLinkify.addLinks(sp, Linkify.WEB_URLS);

如何设置超链接颜色

上边如果设置,就可以完成基本功能,但是安装在不同的手机上,超链接的颜色都会不同,比如vivo的一个机子上是黑色的,显示的样式也不一样!

所以,这里只能使用URLSpan手动去匹配,并设置颜色:

        //注意:不要在xml配置android:autoLink属性        SpannableString sp = new SpannableString(str);        //这句很重要,也可以添加自定义正则表达式        Linkify.addLinks(sp, Linkify.WEB_URLS);        //主要是获取span的位置        URLSpan[] spans = sp.getSpans(0, str.length(), URLSpan.class);        //这里可以用过循环处理就可以动态实现文本颜色的差别化了        //设置高亮样式一        for (URLSpan span : spans) {            sp.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.base_blue)), sp.getSpanStart(span), sp.getSpanEnd(span), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        }        //SpannableString对象设置给TextView        mTv.setText(sp);        //设置TextView可点击        mTv.setMovementMethod(LinkMovementMethod.getInstance());

问题,textview点击事件失效

为什么会出现这样的问题,是因为LinkMovementMethod中onTouchEvent(MotionEvent event),在ACTION_UP事件中,返回了true,表示这里已经消费了up事件,那么自然不会再响应它的点击事件!
所以,这里的解决方案:
我在stackoverflow上找到一个回答:listview-textview-with-linkmovementmethod-makes-list-item-unclickable

public class LinkTextView extends android.support.v7.widget.AppCompatTextView {    boolean dontConsumeNonUrlClicks = true;    boolean linkHit;    public LinkTextView(Context context) {        super(context);    }    public LinkTextView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public LinkTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        linkHit = false;        boolean res = super.onTouchEvent(event);        if (dontConsumeNonUrlClicks)            return linkHit;        return res;    }    public static class LocalLinkMovementMethod extends LinkMovementMethod {        static LocalLinkMovementMethod sInstance;        public static LocalLinkMovementMethod getInstance() {            if (sInstance == null)                sInstance = new LocalLinkMovementMethod();            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);                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 LinkTextView) {                        ((LinkTextView) widget).linkHit = true;                    }                    return true;                } else {                    Selection.removeSelection(buffer);                    Touch.onTouchEvent(widget, buffer, event);                    return false;                }            }            return Touch.onTouchEvent(widget, buffer, event);        }    }}

然后在使用的时候:

//设置TextView可点击,并且调用自定义的LinkMovementMethod,不是url,返回false,否则会消费掉点击事件mTv.setMovementMethod(LinkTextView.LocalLinkMovementMethod.getInstance());

首先我们自定义一个TextView,定义一个布尔值,是否点击了超链接,然后我们继承LinkMovementMethod,在他的onTouchEvent中,如果确实是点击的span,则将上边的属性置为true,然后在TextView的onTouchEvent中,返回这个属性即可!(如果点击的是超链接,return true,如果不是超链接,则return false,事件会继续往下分发,检查是否注册的有点击事件,而去响应点击事件!)

更多相关文章

  1. 巧用布局文件实现Android中实现事件监听机制
  2. Android Layout的layout_height等属性为什么有时会不起作用?
  3. 一步步探索学习Android Touch事件分发传递机制(一)
  4. Android background tint颜色渲染
  5. shape基本用法及全部属性定义
  6. Android Button及TextView动态变换颜色
  7. 【Android】ViewPager实现图片左右滑动播放及添加点击事件
  8. Android RadioButton设置选中时文字和背景颜色同时改变
  9. [转]Android高手进阶教程(四)之----Android 中自定义属性(attr.x

随机推荐

  1. android 设置EditText不可编辑内容,响应点
  2. Android内存泄露及分析
  3. android 下拉窗口菜单的实现(popupwindow)
  4. Android NDK开发下使用C/C++的几个概念
  5. Android面试题(27)-android的事件分发机制
  6. android的语言切换-应用程序 根据 不同的
  7. android三级缓存详解
  8. android连接onenet之获取onenet数据流和
  9. android:异步任务asyncTask介绍及异步任
  10. Android相机实时自动对焦的完美实现(带源