您的位置:首页 > 移动开发 > Android开发

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

2013-07-18 12:50 573 查看



Posted on 2011-07-12 20:50 米其林的微笑 阅读(1495) 评论(3) 编辑 收藏

  如同新浪微博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;

publicclass Defs {

publicstaticfinal String MENTIONS_SCHEMA ="devdiv://sina_profile";

publicstaticfinal String TRENDS_SCHEMA ="devdiv://sina_profile1";

publicstaticfinal 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;

publicclass MentionsActivity extends Activity
{

privatestaticfinal String TAG ="MentionsActivity";

privatestaticfinal Uri PROFILE_URI = Uri.parse(Defs.MENTIONS_SCHEMA);

private String uid;

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

extractUidFromUri();

setTitle("Profile:Hello, "+ uid);

}

privatevoid 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;

publicclass TrendsActivity extends Activity
{

privatestaticfinal String TAG ="TrendsActivity";

privatestaticfinal Uri PROFILE_URI = Uri.parse(Defs.TRENDS_SCHEMA);

private String uid;

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

extractUidFromUri();

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

}

privatevoid 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;

publicclass MainActivity extends Activity
{

privatestaticfinal String TAG ="MainActivity";

@Override

publicvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

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

extractMention2Link(txt);

}

publicstaticvoid 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

publicboolean 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);

}

});
/**
这是用于http连接的匹配,若不希望http用系统的浏览器连接,在textView的属性中不加autolink,加上这段话
Pattern urlsPattern = Pattern.compile("(http://|https://){1}[\\w\\.\\-/:]+");

String urlsScheme = String.format("%s/?%s=", DefineWeiboAutoLink.URLS_SCHEMA, DefineWeiboAutoLink.PARAM_UID);

Linkify.addLinks(v, urlsPattern, urlsScheme, null, new TransformFilter() {

@Override

public String transformUrl(Matcher match, String url) {

return match.group(0);

}

});

配置和“##”一样
*/

}

}

第八步:修改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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐