Android应用实例之---使用Linkify + 正则式区分微博文本链接及跳转处理

原文链接

如同新浪微博Android版的应用上,当我们点击微博文本上的链接会自动跳转界面,或网站链接跳转网页浏览,或邮箱链接跳转邮箱服务,或电话号码链接跳转拨号界面。Android 帮我们设计了一个类:Linkify

  Linkify是一个辅助类,通过RegEx样式匹配,自动地在TextView类(和继承的类)中创建超链接。符合特定的RegEx样式的文本会被转变成可点击的超链接,这些超链接隐式地调用startActivity(new Intent(Intent.ACTION_VIEW, uri)),符合的文本会作为目标URI。

  你可以指定任意的字符串样式为链接,Linkify类提供了预置的通用内容类型(如电话号码和e-mail、web地址)。

Java代码:  

TextView textView  =  (TextView)findViewById(R.id.myTextView);
Linkify.addLinks(textView, Linkify.WEB_URLS
| Linkify.EMAIL_ADDRESSES);

  可以在layout资源里使用android:autoLink特性来为View制作链接。它支持一个或多个(用|分割)自定义的值:none、web、email、phone或all。接下来的XML片段显示了如何为电话号码和e-mail地址添加超链接:

复制代码
< TextView 
android:id ="@+id/txt"  
android:layout_width
="fill_parent"  
android:layout_height
="wrap_content"  
android:text
="@string/hello"
android:textColor
="#FFFFFF"  
android:textColorLink
="#0082CB"
android:autoLink
="web|phone|email" >
</ TextView >
复制代码

 创建自定义的链接字符串:

  为了定义自己的链接字符串,你需要创建一个RegEx样式来匹配文本,进而显示成超链接。和本地类型一样,通过调用Linkify.addLinks来指定目标View,但这次,传入的是新的RegEx样式。你还可以传入一个前缀,当链接点击时,它会添加到目标URI上。

 

int  flags  =  Pattern.CASE_INSENSITIVE;
Pattern p 
=  Pattern.compile(“\\bquake[ 0 - 9 ] * \\b”, flags);
Linkify.addLinks(myTextView, p, “content:
// com.paad.earthquake/earthquakes/”);

  关于Linkify的相关介绍到此结束,现在开始实现使用Linkify + 正则式实现类似微博链接界面跳转,一步一步简单做一个DEMO。

第一步:新建一个Android工程命名为LinkTest;

第二步:在Res/values下新建一个strings.xml资源文件,存储微博文本数据;

 

<? xml version="1.0" encoding="utf-8" ?>
< resources >
< string  name ="hello" > 【官员辱骂采访记者被微博曝光后遭通报批评】5月4日,新疆人民广播电台@新疆新闻广播孙建忠 在喀什地区建设局采访时,遭行政办公室主任霍敏辱骂,后被微博曝光,霍敏当天被建设局通报批评,扣罚一个月工资并取消年终评优资格。孙建忠称已接到霍敏电话说要当面道歉。http://t.cn/hg3PxV </ string >
< string  name ="app_name" > LinkTest </ string >
</ resources >

 

 

 

第三步:修改main.xml布局文件,此处仅添加了一个TextView 作为微博文本的载体;

 

复制代码
<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation
="vertical"  android:layout_width ="fill_parent"
android:layout_height
="fill_parent" >
< TextView  android:id ="@+id/txt"  android:layout_width ="fill_parent"
android:layout_height
="wrap_content"  android:text ="@string/hello"
android:textColor
="#FFFFFF"  android:textColorLink ="#0082CB"
android:autoLink
="web|phone|email" />
</ LinearLayout >
复制代码

 

第四步:定义一个公共类Defs.java,用来存放自定义链接字符串;

复制代码
package  com.linkTest;

public class  Defs {
public static final  String MENTIONS_SCHEMA  = " devdiv://sina_profile " ;
public static final  String TRENDS_SCHEMA  = " devdiv://sina_profile1 " ;
public static final  String PARAM_UID  = " uid " ;
}
复制代码

第五步:定义一个类MentionsActivity.java,用于微博文本上"@"提及的链接跳转界面;

复制代码
package  com.linkTest;

import  android.app.Activity;
import  android.net.Uri;
import  android.os.Bundle;
import  android.util.Log;

public class  MentionsActivity  extends  Activity {
private static final  String TAG  = " MentionsActivity " ;
private static final  Uri PROFILE_URI  =  Uri.parse(Defs.MENTIONS_SCHEMA);

private  String uid;

@Override
protected void  onCreate(Bundle savedInstanceState) {
//  TODO Auto-generated method stub
super .onCreate(savedInstanceState);
extractUidFromUri();
setTitle(
" Profile:Hello,  " +  uid);
}


private void  extractUidFromUri() {
Uri uri 
=  getIntent().getData();
if  (uri  != null &&  PROFILE_URI.getScheme().equals(uri.getScheme())) {
uid 
=  uri.getQueryParameter(Defs.PARAM_UID);
Log.d(TAG, 
" uid from url:  " +  uid);
}
}
}
复制代码

第六步:定义一个类TrendsActivity.java,用于微博文本上"##"话题的链接跳转界面;

复制代码
package  com.linkTest;

import  android.app.Activity;
import  android.net.Uri;
import  android.os.Bundle;
import  android.util.Log;

public class  TrendsActivity  extends  Activity {
private static final  String TAG  = " TrendsActivity " ;
private static final  Uri PROFILE_URI  =  Uri.parse(Defs.TRENDS_SCHEMA);

private  String uid;

@Override
protected void  onCreate(Bundle savedInstanceState) {
//  TODO Auto-generated method stub
super .onCreate(savedInstanceState);

extractUidFromUri();
setTitle(
" Profile1:Hello,  " +  uid);
}


private void  extractUidFromUri() {
Uri uri 
=  getIntent().getData();
if  (uri  != null &&  PROFILE_URI.getScheme().equals(uri.getScheme())) {
uid 
=  uri.getQueryParameter(Defs.PARAM_UID);
Log.d(TAG, 
" uid from url:  " +  uid);
}
}
}
复制代码

 

第七步:定义应用实例的主界面类MainActivity.java,该类使用Linkify + 正则式区分微博文本链接,处理跳转界面;

复制代码
package  com.linkTest;

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

import  android.app.Activity;
import  android.os.Bundle;
import  android.text.util.Linkify;
import  android.text.util.Linkify.MatchFilter;
import  android.text.util.Linkify.TransformFilter;
import  android.util.Log;
import  android.widget.TextView;

public class  MainActivity  extends  Activity {

private static final  String TAG  = " MainActivity " ;

@Override
public void  onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.main);

TextView txt 
=  (TextView) findViewById(R.id.txt);
extractMention2Link(txt);
}

public static void  extractMention2Link(TextView v) {
v.setAutoLinkMask(
0 );

Pattern mentionsPattern 
=  Pattern.compile( " @(\\w+?)(?=\\W|$)(.) " );
String mentionsScheme 
=  String.format( " %s/?%s= " , Defs.MENTIONS_SCHEMA, Defs.PARAM_UID);
Linkify.addLinks(v, mentionsPattern, mentionsScheme, 
new  MatchFilter() {

@Override
public boolean  acceptMatch(CharSequence s,  int  start,  int  end) {

return  s.charAt(end - 1 != ' . ' ;
}

}, 
new  TransformFilter() {
@Override
public  String transformUrl(Matcher match, String url) {
Log.d(TAG, match.group(
1 ));
return  match.group( 1 ); 
}
});

Pattern trendsPattern 
=  Pattern.compile( " #(\\w+?)# " );
String trendsScheme 
=  String.format( " %s/?%s= " , Defs.TRENDS_SCHEMA, Defs.PARAM_UID);
Linkify.addLinks(v, trendsPattern, trendsScheme, 
null new  TransformFilter() {
@Override
public  String transformUrl(Matcher match, String url) {
Log.d(TAG, match.group(
1 ));
return  match.group( 1 ); 
}
});


}
复制代码

第八步:修改AndroidManifest.xml,注册应用实例的所有Activity。

复制代码
<? xml version="1.0" encoding="utf-8" ?>
< manifest  xmlns:android ="http://schemas.android.com/apk/res/android"
android:versionCode
="1"  android:versionName ="1.0"  package ="com.linkTest" >
< application  android:icon ="@drawable/icon"  android:label ="@string/app_name" >
< activity  android:name ="MainActivity"  android:label ="@string/app_name" >
< intent-filter >
< action  android:name ="android.intent.action.MAIN" />
< category  android:name ="android.intent.category.LAUNCHER" />
</ intent-filter >
</ activity >

< activity  android:name ="MentionsActivity" >
< intent-filter >
< action  android:name ="android.intent.action.VIEW" />
< category  android:name ="android.intent.category.DEFAULT" />
< category  android:name ="android.intent.category.BROWSABLE" />
< data  android:scheme ="devdiv"  android:host ="sina_profile" />
</ intent-filter >
</ activity >
< activity  android:name ="TrendsActivity" >
< intent-filter >
< action  android:name ="android.intent.action.VIEW" />
< category  android:name ="android.intent.category.DEFAULT" />
< category  android:name ="android.intent.category.BROWSABLE" />
< data  android:scheme ="devdiv"  android:host ="sina_profile1" />
</ intent-filter >
</ activity >
</ application >
</ manifest >
复制代码

最后一步:运行上述Android工程,效果如下图所示:

到此,就结束了使用Linkify + 正则式区分微博文本链接及跳转处理。

注:本文的代码在论坛DEMO的基础上做了修改,但在提及用户@的正则式表达,存在问题,如遇到"-"存在不能正确区分,如果有哪位前辈无意中浏览了文章,望不吝赐教,能对问题予以指点,我将感激不尽。

部分引用:http://www.eoeandroid.com/thread-67225-1-1.html

     http://www.devdiv.com/thread-35696-1-1.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值