autoLink属性
1、none:表示不进行任何匹配,默认;
2、Web:表示匹配Web Url,如:内容中的http://www.baidu.com会成为可单击跳转的超链接;
3、Email:表示匹配邮件地址:如:邮件地址为hello@com.cn会成为可单击的超链接;
4、Phone:表示匹配电话号码:如:点击号码10086会跳到拨号界面;
5、Map:表示匹配地图地址;
6、All:表示将会匹配web、email、phone、map;
拦截超链接
点击web地址时打开后跳转的是手机自带的浏览器,如果希望点击web地址时可以跳转到应用本身的一个WebView界面,那么此时又该如何实现呢
总之在经过一系列的翻阅跟TextView相关的源码和帮助文档后,发现我们可以通过借助Spannable来获取URLSpan数组然后可以通过遍历获取所有的url地址,最后通过给Spannable设置自定义的ClickableSpan来进行跳转
主要代码如下:
public class MainActivity extends Activity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.text);
interceptHyperLink(textView);
}
/**
* 拦截超链接
* @param tv
*/
private void interceptHyperLink(TextView tv) {
tv.setMovementMethod(LinkMovementMethod.getInstance());
CharSequence text = tv.getText();
if (text instanceof Spannable) {
int end = text.length();
Spannable spannable = (Spannable) tv.getText();
URLSpan[] urlSpans = spannable.getSpans(0, end, URLSpan.class);
if (urlSpans.length == 0) {
return;
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
// 循环遍历并拦截 所有http://开头的链接
for (URLSpan uri : urlSpans) {
String url = uri.getURL();
if (url.indexOf("http://") == 0) {
CustomUrlSpan customUrlSpan = new CustomUrlSpan(this,url);
spannableStringBuilder.setSpan(customUrlSpan, spannable.getSpanStart(uri),
spannable.getSpanEnd(uri), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
tv.setText(spannableStringBuilder);
}
}
public class CustomUrlSpan extends ClickableSpan {
private Context context;
private String url;
public CustomUrlSpan(Context context,String url){
this.context = context;
this.url = url;
}
@Override
public void onClick(View widget) {
// 在这里可以做任何自己想要的处理
Intent intent = new Intent(context,WebViewActivity.class);
intent.putExtra("weburl",url);
context.startActivity(intent);
}
}
}
2)去除超链接的下划线
从源码中可以发现,超链接中的下划线是通过TextPaint的setUnderlineText方法来实现的,也就是说如果我们想去除超链接中的下划线的话可以通过自定义一个继承自ClickableSpan的类然后重写其updateDrawState方法,在该方法中将TextPaint的setUnderlineText方法设为false,最后再将该自定义的ClickableSpan设置到的相应的TextView中即可
原则上来说通过自定义一个继承自ClickableSpan的类是可以去除超链接的下划线,但是,在这里我将使用跟ClickableSpan类似的一个类UnderlineSpan来实现
1)首先自定义一个继承自UnderlineSpan类的NoUnderlineSpan类并重写父类的updateDrawState方法,然后在该方法中将TextPaint的setUnderlineText方法设为false,主要代码如下
private class NoUnderlineSpan extends UnderlineSpan {
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
}
2)在需要去除超链接下划线的Activity中的相应TextView后设置如下内容:
private void removeHyperLinkUnderline(TextView tv) {
CharSequence text = tv.getText();
if(text instanceof Spannable){
Log.i("test","true");
Spannable spannable = (Spannable) tv.getText();
NoUnderlineSpan noUnderlineSpan = new NoUnderlineSpan();
spannable.setSpan(noUnderlineSpan,0,text.length(), Spanned.SPAN_MARK_MARK);
}
}
效果
自定义链接
除了以上通过添加autoLink属性并设置web值实现超链接以外,android还给我们提供了一个Linkify类来自定义超链接,并且从帮助文档中可以看出Linkify还提供了一大堆添加自定义模式的方法
这里为了方便,暂且用有3个参数的构造方法即最后一个,其中第一个参数TextView即需要自定义模式的对象,第二个参数Pattern表示自己定义的用来匹配第一个参数TextView中内容的正则表达式,最后一个参数Scheme我理解为当点击自定义链接时跳转的界面
如:在布局文件中新增一个TextView并设置一些默认的内容,然后在代码如下通过如下方式设置自定义链接
Pattern pattern = Pattern.compile("abc://\\S*");
Linkify.addLinks(textView,pattern,"abc");
为了当点击自定义链接时点击能够响应,在这里新建了一个WebViewActivity类专门用来处理响应,但是有一点需要注意是需要在AndroidManifest清单文件中相应的activity节点下添加如下代码
效果如图:
当然,我们也可以通过这种方法实现上面所实现的拦截超链接的功能,这里就不再详细说明了
另外,当一个TextView即需要使用内置模式又需要使用自定义模式时必须先声明内置模式然后再声明自定义模式,并且经测试发现:不能在xml布局文件中通过autoLink属性来声明内置模式,否则自定义模式不起作用
xml代码
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内置模式:拨打电话10086\n自定义链接:abc://baidu.com"
android:layout_marginTop="10dp"/>
java代码
textView = (TextView)findViewById(R.id.text);
//多种模式
Linkify.addLinks(textView,Linkify.PHONE_NUMBERS);
Pattern pattern = Pattern.compile("abc://\\S*");
Linkify.addLinks(textView, pattern, "abc");
效果:
借助SpannableString定制超链接的跳转
主要代码
//借助SpannableString类实现超链接文字
textView = (TextView)findViewById(R.id.text);
textView.setText(getClickableSpan());
//设置超链接可点击
textView.setMovementMethod(LinkMovementMethod.getInstance());
/**
* 获取可点击的SpannableString
* @return
*/
private SpannableString getClickableSpan() {
SpannableString spannableString = new SpannableString("使用该软件,即表示您同意该软件的使用条款和隐私政策");
//设置下划线文字
spannableString.setSpan(new UnderlineSpan(), 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的单击事件
spannableString.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this,"使用条款", Toast.LENGTH_SHORT).show();
}
}, 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的前景色
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置下划线文字
spannableString.setSpan(new UnderlineSpan(), 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的单击事件
spannableString.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this,"隐私政策",Toast.LENGTH_SHORT).show();
}
}, 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的前景色
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;
}
效果
原文请戳这里