SpannableString对微博内容的处理(超链接、用户名、主题点击跳转)

 

实现上面图像的效果,点击超链接跳转到对应链接,点击用户名或主题跳转到其他Activity并把用户名作为参数传递过去。同时实现区分邮箱跟用户的混淆

(如上面lau@qq.com不会被认为有一个用户@qq.com)

 

SpannableStringDemoActivity.java

 

package com.lau.spannablestring;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;

public class SpannableStringDemoActivity extends Activity {

	TextView textView = null;
	
	final static String string = "#刘翔# //@李开复: @薛蛮子:@李开复: @李开复:@李开复:@李开复:lau@qq.com " +
			"http://www.baidu.com/index.php?tn=360se_dg " +
			"转发// //@新周刊:@李承鹏:@财经网: Email:lau@qq.com又是公安牵头。@李承鹏@李承鹏@李承鹏@李承鹏:随时随刻离不开暴力。";
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView) findViewById(R.id.textView1);
        
        ssb.append(string);
        findAt(string, 0);
        findTheme(string, 0);
        findLink(string, 0);
        findEmail(string, 0);
        
        textView.setText(ssb);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
    }

	private static final String STR_PATTERN_AT = "@[\\u4e00-\\u9fa5\\w\\-]+";
	private static final String STR_PATTERN_THEME = "#[^\\#|.]+#";
	private static final String STR_PATTERN_LINK = "http://[&=?/\\.\\w]+";
	private static final String STR_PATTERN_EMAIL = "\\w+(\\.\\w+)*@\\w+(\\.\\w+)+";
	
	private static final Pattern mPatternAt = Pattern.compile(STR_PATTERN_AT);
	private static final Pattern mPatternTheme = Pattern.compile(STR_PATTERN_THEME);
	private static final Pattern mPatternLink = Pattern.compile(STR_PATTERN_LINK);
	private static final Pattern mPatternEmail = Pattern.compile(STR_PATTERN_EMAIL);

	private SpannableStringBuilder ssb = new SpannableStringBuilder();
	private Matcher matcher = null;
    
	//从位置pos开始查找@关键字
	void findAt(String str, int pos) {
		if(str == null || str.length() == 0) {
			return;
		}
		matcher = mPatternAt.matcher(str);
		if(matcher.find()) {
			final String find = matcher.group();
			final int start = str.indexOf(find) + pos;
			final int end = start + find.length();
			MyClickableSpan clickableSpan = new MyClickableSpan(string.substring(start, end));
			ssb.setSpan(clickableSpan, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
			pos = end;
			findAt(string.substring(end), pos);
		}
	}
	
	//从位置pos开始查找##关键字
	void findTheme(String str, int pos) {
		if(str == null || str.length() == 0) {
			return;
		}
		matcher = mPatternTheme.matcher(str);
		if(matcher.find()) {
			final String find = matcher.group();
			final int start = str.indexOf(find) + pos;
			final int end = start + find.length();
			MyClickableSpan clickableSpan = new MyClickableSpan(string.substring(start, end));
			ssb.setSpan(clickableSpan, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
			pos = end;
			findTheme(string.substring(end), pos);
		}
	}
	
	//从位置pos开始查找链接关键字
	void findLink(String str, int pos) {
		if(str == null || str.length() == 0) {
			return;
		}
		matcher = mPatternLink.matcher(str);
		if(matcher.find()) {
			final String find = matcher.group();
			final int start = str.indexOf(find) + pos;
			final int end = start + find.length();
			URLSpanNotUnderLine urlSpan = new URLSpanNotUnderLine(string.substring(start, end));
			ssb.setSpan(urlSpan, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
			pos = end;
			findLink(string.substring(end), pos);
		}
	}
	
	//从位置pos开始查找邮箱
	void findEmail(String str, int pos) {
		if(str == null || str.length() == 0) {
			return;
		}
		matcher = mPatternEmail.matcher(str);
		if(matcher.find()) {
			final String find = matcher.group();
			final int start = str.indexOf(find) + pos;
			final int end = start + find.length();
			CharacterStyle[] span =  ssb.getSpans(start, end, CharacterStyle.class);
			if(span != null) {
				for(int i=0; i<span.length; i++) {
					ssb.removeSpan(span[i]);
				}
			}
			pos = end;
			findEmail(string.substring(end), pos);
		}
	}
	
	class URLSpanNotUnderLine extends URLSpan {
		public URLSpanNotUnderLine(String url) {
			super(url);
		}
		@Override
		public void onClick(View widget) {
			super.onClick(widget);
		}
		@Override
		public void updateDrawState(TextPaint ds) {
			super.updateDrawState(ds);
			ds.setUnderlineText(false);		//
		}
	}
	
	class MyClickableSpan extends ClickableSpan {

		String str = null;
		
		public MyClickableSpan(String str) {
			this.str = str;
		}
		@Override
		public void updateDrawState(TextPaint ds) {
			super.updateDrawState(ds);
			ds.setUnderlineText(false);
		}
		@Override
		public void onClick(View widget) {
			Intent intent = new Intent();
			intent.setClass(getApplicationContext(), OtherActivity.class);
			intent.putExtra("name", str);
			startActivity(intent);
		}
	}
	
}


 


 

参考链接


http://www.dewen.org/q/1744
http://truelife.sinaapp.com/?p=303

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值