标签

Android 44

Android Network security configuration Android 网络配置 Android Camera Preview gradlew 源码分析 Android 动态修改菜单 Android RelativeLayout 之 Gravity 的使用 Android Studio Gradle Download Error Android加载子View 【转】Android打开与关闭软键盘 Android EditText软键盘显示隐藏以及“监听” Android mipmap文件夹 Android 用命令行更新SDK Android Service学习之AIDL, Parcelable和远程服务 Android 5.0设备中,Notification小图标是白色的 Android最佳实践 Android Keystore 文件的密码修改 Android Studio 中加载so库文件 Android 中方法重载遇到的问题 ListView & RecyclerView Google Volley如何缓存HTTP请求文件 Creating logs in Android applications Advanced Android TextView TextView高亮URL地址解析 TextView 高亮URL地址,并实现跳转 Best practices in Android development Android Sdk Manager无法更新问题解决办法 Android ViewPager滑动事件 Google Volley 网络请求框架(一) Andorid UI注入工具的使用(ButterKnife) Android 项目中出现的奇葩bug, 数据NullPointExcption Android Drawable Animation Android 图片的毛玻璃效果 Android之使用Log打印日志 使用Fidder来拦截Android发送的HTTP请求 Android之Webview使用 Android之Notification的使用(二) Android之Notification的使用(一) Android Keyboard Show&Hiden Android 粘贴板的使用 Android中使用.9.png 使用Fidder来拦截Android发送的HTTP请求 Andorid JUnit 单元测试 Activity之间的切换动画 Android ListView中Adapter的使用

TextView高亮URL地址解析

2015年01月16日

#TextView 高亮实现

基本使用方法:

textView.setAutoLinkMask(Linkify.ALL);
//public static final int WEB_URLS = 1;
//public static final int EMAIL_ADDRESSES = 2;
//public static final int PHONE_NUMBERS = 4;
//public static final int MAP_ADDRESSES = 8; 
//public static final int ALL = 15;
textView.setMovementMethod(LinkMovementMethod.getInstacne());

setMovementMethod()是设置相应点击跳转时间触发用的。

去研究了一下TextView的源码。URL地址匹配实际上是用的正则做的。 所以我们也能很简单的实现这个东西。

#修改源码,实现自己的高亮和自定义跳转

首先拿到我们要显示的字符串,创建Spannable对象:

private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance();
Spannable spannable = mSpannableFactory.newSpannable(pili.description);

然后我们要去拿到的spannable进行处理,将我们要高亮的数据正则匹配出来。

  1. 先移除掉spannable中已经存在的URLSpan
	URLSpan[] old = text.getSpans(0, text.length(), URLSpan.class);
	for (int i = old.length - 1; i >= 0; i--) {
	  text.removeSpan(old[i]);
	}
  1. 匹配URL地址,并设置Spannable
  public static final Linkify.MatchFilter sUrlMatchFilter = new Linkify.MatchFilter() {
   		public final boolean acceptMatch(CharSequence s, int start, int end) {
       	if (start == 0) {
           	return true;
       	}

       	if (s.charAt(start - 1) == '@') {
           	return false;
       	}
       	return true;
   		}
  };
  private static final String makeUrl(String url, String[] prefixes,
                                        Matcher m, Linkify.TransformFilter filter) {
        if (filter != null) {
            url = filter.transformUrl(m, url);
        }

        boolean hasPrefix = false;

        for (int i = 0; i < prefixes.length; i++) {
            if (url.regionMatches(true, 0, prefixes[i], 0,
                    prefixes[i].length())) {
                hasPrefix = true;

                // Fix capitalization if necessary
                if (!url.regionMatches(false, 0, prefixes[i], 0,
                        prefixes[i].length())) {
                    url = prefixes[i] + url.substring(prefixes[i].length());
                }

                break;
            }
        }

        if (!hasPrefix) {
            url = prefixes[0] + url;
        }
        return url;
    }
    
	private final void gatherLinks(ArrayList<LinkSpec> links,
	                                     Spannable s, Pattern pattern, String[] schemes,
	                                     Linkify.MatchFilter matchFilter, 
	                                     Linkify.TransformFilter transformFilter) {
	   Matcher m = pattern.matcher(s); // 正则匹配,使用Patterns.WEB_URL
	   while (m.find()) {
	       int start = m.start();
	       int end = m.end();

	       if (matchFilter == null || matchFilter.acceptMatch(s, start, end)) {
	           LinkSpec spec = new LinkSpec();
	           String url = makeUrl(m.group(0), schemes, m, transformFilter);
	           spec.url = url;
	           spec.start = start;
	           spec.end = end;
	           links.add(spec);
	       }
	   }
	 }
	 class LinkSpec {
        String url;
        int start;
        int end;
    }
    private final void applyLink(String url, int start, int end, Spannable text) {
        URLSpanNoUnderline span = new URLSpanNoUnderline(url);
        text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    public class URLSpanNoUnderline extends ClickableSpan {
        private final String mURL;
        public URLSpanNoUnderline(String url) {
            mURL = url;
        }

        public String getURL() {
            return mURL;
        }

        @Override
        public void onClick(View widget) {
            final Context context = widget.getContext();
            BrowserActivity.startActivity(context, mURL);
        }
        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);  //取消下划线
            ds.setColor(0xff0066ff);     //指定文字颜色
            //ds.setTextSize(ds.getTextSize()*1.1F);
        }
    }


友情链接: Hiro's Blog | Junjun's Blog