前言

我们在给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. [置顶] 如何演示你的App?Android录制Gif动态图教程
  2. Android中的通知—Notification
  3. android:maxHeight,android:maxWidth失效
  4. 一步步探索学习Android(安卓)Touch事件分发传递机制(一)
  5. android之CalendarView日历视图
  6. 巧用布局文件实现Android中实现事件监听机制
  7. intellij idea 设置用真机测试android
  8. android Dependencies ,Private Libraries ,Referenced Libraries
  9. Flutter与Android的差异性

随机推荐

  1. android 界面布局 很好的一篇总结
  2. 通过ua检测浏览页面的设备是phone还是tab
  3. Android中数据存储的5中方法
  4. Android入门讲解(一)
  5. 网络请求框架(Volley)
  6. Android缺少awk:安装busybox
  7. Android(安卓)开发之多线程处理、Handler
  8. Android(安卓)Studio NDK开发案例一 JNI
  9. Android FileObserver 用法
  10. Android Binder------ServiceManager启动